studio - superponer graficas en r
Aplicar la funciĆ³n a cada columna en un marco de datos observando el tipo de datos existente en cada columna (4)
Estoy tratando de obtener el mínimo / máximo para cada columna en un marco de datos grande, como parte de conocer mis datos . Mi primer intento fue:
apply(t,2,max,na.rm=1)
Trata todo como un vector de caracteres, porque las primeras columnas son tipos de caracteres. Así que el máximo de algunas de las columnas numéricas está saliendo como " -99.5"
.
Entonces intenté esto:
sapply(t,max,na.rm=1)
pero se queja de que el max no tiene sentido por factores . ( lapply
es lo mismo.) Lo que me confunde es que apply
pensamiento max
fue perfectamente significativo para factores, por ejemplo, devolvió "ZEBRA" para la columna 1.
Por cierto, eché un vistazo a Uso de sapply en el vector de POSIXct y una de las respuestas dice " Cuando usas sapply, tus objetos son obligados a numérico, ... ". ¿Esto es lo que me está pasando? Si es así, ¿existe una función de aplicación alternativa que no obligue? Seguramente es una necesidad común, ya que una de las características clave del tipo de marco de datos es que cada columna puede ser de un tipo diferente.
La razón por la que max
funciona con apply
es que apply
es forzar su marco de datos a una matriz primero, y una matriz solo puede contener un tipo de datos. Así que terminas con una matriz de personajes. sapply
es solo una envoltura para lapply
, por lo que no es sorprendente que ambos produzcan el mismo error.
El comportamiento predeterminado al crear un marco de datos es que las columnas categóricas se almacenen como factores . A menos que especifique que es un factor ordenado , las operaciones como max
y min
no estarán definidas, ya que R supone que ha creado un factor desordenado .
Puede cambiar este comportamiento especificando options(stringsAsFactors = FALSE)
, que cambiará el valor predeterminado para toda la sesión, o puede pasar stringsAsFactors = FALSE
en la llamada de construcción data.frame()
. Tenga en cuenta que esto solo significa que el valor min
y el max
asumirán el orden "alfabético" de forma predeterminada.
O puede especificar manualmente un orden para cada factor, aunque dudo que eso sea lo que quiere hacer.
En cualquier caso, en cualquier caso, la sapply
generará generalmente un vector atómico, que implicará convertir todo en caracteres. Una forma de evitar esto es la siguiente:
#Some test data
d <- data.frame(v1 = runif(10), v2 = letters[1:10],
v3 = rnorm(10), v4 = LETTERS[1:10],stringsAsFactors = TRUE)
d[4,] <- NA
#Similar function to DWin''s answer
fun <- function(x){
if(is.numeric(x)){max(x,na.rm = 1)}
else{max(as.character(x),na.rm=1)}
}
#Use colwise from plyr package
colwise(fun)(d)
v1 v2 v3 v4
1 0.8478983 j 1.999435 J
Si desea conocer su summary (df)
datos summary (df)
proporcione el mínimo, el primer cuantil, la mediana y la media, el tercer cuantil y el máximo de las columnas numéricas y la frecuencia de los niveles superiores de las columnas de factores.
Si fuera un "factor ordenado" las cosas serían diferentes. Lo que no quiere decir que me gusten los "factores ordenados", no lo hago, solo para decir que algunas relaciones se definen para los "factores ordenados" que no se definen para los "factores". Los factores son considerados como variables categóricas ordinarias. Usted está viendo el orden natural de factores, que es el orden léxico alfabético para su localidad. Si desea obtener una coacción automática a "numérico" para cada columna, ... fechas y factores y todo, intente:
sapply(df, function(x) max(as.numeric(x)) ) # not generally a useful result
O si desea probar los factores primero y regresar como espera, entonces:
sapply( df, function(x) if("factor" %in% class(x) ) {
max(as.numeric(as.character(x)))
} else { max(x) } )
El comentario de @Darrens funciona mejor:
sapply(df, function(x) max(as.character(x)) )
max
tiene éxito con los vectores de caracteres.
aprovechando la respuesta de @ltamar:
Usa resumen y munge la salida en algo útil!
library(tidyr)
library(dplyr)
df %>%
summary %>%
data.frame %>%
select(-Var1) %>%
separate(data=.,col=Freq,into = c(''metric'',''value''),sep = '':'') %>%
rename(column_name=Var2) %>%
mutate(value=as.numeric(value),
metric = trimws(metric,''both'')
) %>%
filter(!is.na(value)) -> metrics
No es bonito y ciertamente no es rápido, ¡pero hace el trabajo!