Determinar los tipos de datos de las columnas de un marco de datos

153

Estoy usando R y he cargado datos en un marco de datos usando read.csv(). ¿Cómo determino el tipo de datos de cada columna en el marco de datos?

stackoverflowuser2010
fuente
¿Programáticamente (p. Ej., sapply(..., class))Interactivamente (p str(...). Ej. ) O ambos? Por lo general, es más escalable hacerlo programáticamente, luego puede arbitrariamente Filter(...)la lista de enteros, caracteres, factores, etc. O puede usar grep/greplpara inferir tipos de columnas names(...)si siguen alguna convención de nomenclatura
smci
@ smci: No pedí 'programáticamente' en mi pregunta original. No sé por qué cambiarías toda la naturaleza de mi pregunta.
stackoverflowuser2010
ok, fue revertido. No cambió toda la naturaleza, lo aclaró en una de dos direcciones. Los enfoques interactivos que se usan str(...)no son escalables y se quedan sin vapor en <100 cols.
smci

Respuestas:

215

Su mejor apuesta para comenzar es usar ?str(). Para explorar algunos ejemplos, hagamos algunos datos:

set.seed(3221)  # this makes the example exactly reproducible
my.data <- data.frame(y=rnorm(5), 
                      x1=c(1:5), 
                      x2=c(TRUE, TRUE, FALSE, FALSE, FALSE),
                      X3=letters[1:5])

La solución de @Wilmer E Henao H es muy simple:

sapply(my.data, class)
        y        x1        x2        X3 
"numeric" "integer" "logical"  "factor" 

El uso le str()brinda esa información más beneficios adicionales (como los niveles de sus factores y los primeros valores de cada variable):

str(my.data)
'data.frame':  5 obs. of  4 variables:
$ y : num  1.03 1.599 -0.818 0.872 -2.682
$ x1: int  1 2 3 4 5
$ x2: logi  TRUE TRUE FALSE FALSE FALSE
$ X3: Factor w/ 5 levels "a","b","c","d",..: 1 2 3 4 5

El enfoque de @Gavin Simpson también está optimizado, pero proporciona información ligeramente diferente de class():

sapply(my.data, typeof)
       y        x1        x2        X3 
"double" "integer" "logical" "integer"

Para obtener más información sobre class, typeofy el hijo del medio mode, vea este excelente hilo SO: una encuesta exhaustiva de los tipos de cosas en R. 'mode' y 'class' y 'typeof' son insuficientes .

gung - Restablece a Monica
fuente
1
Después de usar R durante varios meses, descubrí que str(dataframe)es la forma más rápida de determinar los tipos de columna de un vistazo. Los otros enfoques requieren más pulsaciones de teclas y no muestran tanta información, pero son útiles si los tipos de datos de columna son una entrada a otras funciones.
stackoverflowuser2010
Hola, cuando hice lo mismo con aplicar en lugar de aplicar, no funcionó
Dom Jo
@DomJo, ¿por qué usarías apply()? Eso es para matrices. Un marco de datos es una lista (tipo especial).
Gung - Restablece Mónica el
50
sapply(yourdataframe, class)

Donde yourdataframe es el nombre del marco de datos que está utilizando

Wilmer E. Henao
fuente
18

Yo sugeriría

sapply(foo, typeof)

si necesita los tipos reales de los vectores en el marco de datos. class()es algo así como una bestia diferente.

Si no necesita obtener esta información como un vector (es decir, no necesita que haga otra cosa programáticamente más adelante), simplemente utilícela str(foo).

En ambos casos foose reemplazaría con el nombre de su marco de datos.

Gavin Simpson
fuente
7

Simplemente pase su marco de datos a la siguiente función:

data_types <- function(frame) {
  res <- lapply(frame, class)
  res_frame <- data.frame(unlist(res))
  barplot(table(res_frame), main="Data Types", col="steelblue", ylab="Number of Features")
}

para producir un gráfico de todos los tipos de datos en su marco de datos. Para el conjunto de datos de iris obtenemos lo siguiente:

data_types(iris)

ingrese la descripción de la imagen aquí

Cibernético
fuente
5

Para marcos de datos pequeños:

library(tidyverse)

as_tibble(mtcars)

le da una impresión del df con tipos de datos

# A tibble: 32 x 11
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
 * <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
 3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1

Para marcos de datos grandes:

glimpse(mtcars)

le brinda una vista estructurada de los tipos de datos:

Observations: 32
Variables: 11
$ mpg  <dbl> 21.0, 21.0, 22.8, 21.4, 18.7, 18.1, 14.3, 24.4, 22.8, 19.2, 17.8, 16.4, 17....
$ cyl  <dbl> 6, 6, 4, 6, 8, 6, 8, 4, 4, 6, 6, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4, 8, 8, 8, 8, ...
$ disp <dbl> 160.0, 160.0, 108.0, 258.0, 360.0, 225.0, 360.0, 146.7, 140.8, 167.6, 167.6...
$ hp   <dbl> 110, 110, 93, 110, 175, 105, 245, 62, 95, 123, 123, 180, 180, 180, 205, 215...
$ drat <dbl> 3.90, 3.90, 3.85, 3.08, 3.15, 2.76, 3.21, 3.69, 3.92, 3.92, 3.92, 3.07, 3.0...
$ wt   <dbl> 2.620, 2.875, 2.320, 3.215, 3.440, 3.460, 3.570, 3.190, 3.150, 3.440, 3.440...
$ qsec <dbl> 16.46, 17.02, 18.61, 19.44, 17.02, 20.22, 15.84, 20.00, 22.90, 18.30, 18.90...
$ vs   <dbl> 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, ...
$ am   <dbl> 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, ...
$ gear <dbl> 4, 4, 4, 3, 3, 3, 3, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 4, 4, 4, 3, 3, 3, 3, 3, ...
$ carb <dbl> 4, 4, 1, 1, 2, 1, 4, 2, 2, 4, 4, 3, 3, 3, 4, 4, 4, 1, 2, 1, 1, 2, 2, 4, 2, ...

Para obtener una lista del tipo de datos de las columnas (como dijo anteriormente @Alexandre):

map(mtcars, class)

da una lista de tipos de datos:

$mpg
[1] "numeric"

$cyl
[1] "numeric"

$disp
[1] "numeric"

$hp
[1] "numeric"

Para cambiar el tipo de datos de una columna:

library(hablar)

mtcars %>% 
  convert(chr(mpg, am),
          int(carb))

convierte columnas mpgy amcaracteres y la columna carben entero:

# A tibble: 32 x 11
   mpg     cyl  disp    hp  drat    wt  qsec    vs am     gear  carb
   <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> <dbl> <int>
 1 21        6  160    110  3.9   2.62  16.5     0 1         4     4
 2 21        6  160    110  3.9   2.88  17.0     0 1         4     4
 3 22.8      4  108     93  3.85  2.32  18.6     1 1         4     1
 4 21.4      6  258    110  3.08  3.22  19.4     1 0         3     1
davsjob
fuente
3

Como no se dijo claramente, solo agrego esto:

Estaba buscando una manera de crear una tabla que contenga el número de ocurrencias de todos los tipos de datos .

Digamos que tenemos una data.framecon dos columnas numéricas y una lógica

dta <- data.frame(a = c(1,2,3), 
                  b = c(4,5,6), 
                  c = c(TRUE, FALSE, TRUE))

Puede resumir el número de columnas de cada tipo de datos con ese

table(unlist(lapply(dta, class)))
# logical numeric 
#       1       2 

Esto resulta extremadamente útil, si tiene muchas columnas y desea obtener una visión general rápida.

Para dar crédito: esta solución se inspiró en la respuesta de @Cybernetic .

loki
fuente
2

Aquí hay una función que forma parte del paquete helpRFunctions que devolverá una lista de todos los diversos tipos de datos en su marco de datos, así como los nombres de variables específicos asociados con ese tipo.

install.package('devtools') # Only needed if you dont have this installed.
library(devtools)
install_github('adam-m-mcelhinney/helpRFunctions')
library(helpRFunctions)
my.data <- data.frame(y=rnorm(5), 
                  x1=c(1:5), 
                  x2=c(TRUE, TRUE, FALSE, FALSE, FALSE),
                  X3=letters[1:5])
t <- list.df.var.types(my.data)
t$factor
t$integer
t$logical
t$numeric

Entonces podrías hacer algo como var(my.data[t$numeric]).

Espero que esto sea útil!

ML_Dev
fuente
1
Vale la pena señalar que, bajo el capó, esto es lapply(your_data, class)con un poco de procesamiento adicional para el formateo.
Gregor Thomas el
1

Si importa el archivo csv como data.frame (y no como matriz), también puede usar summary.default

summary.default(mtcars)

     Length Class  Mode   
mpg  32     -none- numeric
cyl  32     -none- numeric
disp 32     -none- numeric
hp   32     -none- numeric
drat 32     -none- numeric
wt   32     -none- numeric
qsec 32     -none- numeric
vs   32     -none- numeric
am   32     -none- numeric
gear 32     -none- numeric
carb 32     -none- numeric
DJV
fuente
1

Otra opción es utilizar la función de mapa del paquete purrr.

library(purrr)
map(df,class)
Alexandre Lima
fuente