Determinare i tipi di dati delle colonne di un frame di dati


153

Sto usando R e ho caricato i dati in un dataframe usando read.csv(). Come posso determinare il tipo di dati di ogni colonna nel frame di dati?


A livello di codice (ad es. sapply(..., class))O interattivamente (ad es. str(...)) O entrambi? In genere è più scalabile per farlo a livello di codice, quindi è possibile arbitrariamente Filter(...)l'elenco di numeri interi, caratteri, fattori ecc. Oppure è possibile utilizzare grep/greplper dedurre i tipi di colonna names(...)se seguono le convenzioni di denominazione
smci,

@smci: non ho chiesto "programmaticamente" nella mia domanda originale. Non so perché cambieresti l'intera natura della mia domanda.
stackoverflowuser2010

ok, è stato ripristinato. Non ha cambiato l'intera natura, lo ha chiarito in una delle due direzioni. Gli approcci interattivi che utilizzano str(...)non sono scalabili ed esauriscono il vapore su <100 cols.
smci,

Risposte:


215

La tua migliore scommessa per iniziare è usare ?str(). Per esplorare alcuni esempi, facciamo alcuni dati:

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 soluzione di @Wilmer E Henao H è molto snella:

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

L'utilizzo str()ti fornisce tali informazioni oltre a extra extra (come i livelli dei tuoi fattori e i primi valori di ciascuna variabile):

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

Anche l'approccio di @Gavin Simpson è semplificato, ma fornisce informazioni leggermente diverse rispetto a class():

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

Per ulteriori informazioni su class, typeofe il bambino di mezzo mode, vedere questo eccellente thread SO: un'indagine completa sui tipi di cose in R. 'mode' e 'class' e 'typeof' non sono sufficienti .


1
Dopo aver usato R per diversi mesi, ho scoperto che str(dataframe)è il modo più veloce per determinare i tipi di colonna a colpo d'occhio. Gli altri approcci richiedono più sequenze di tasti e non mostrano quante più informazioni, ma sono utili se i tipi di dati della colonna sono un input per altre funzioni.
stackoverflowuser2010

Ciao, quando ho fatto lo stesso con apply invece di apply, non ha funzionato
Dom Jo

@DomJo, perché dovresti usare apply()? Questo è per le matrici. Un frame di dati è un elenco (tipo speciale di).
gung - Ripristina Monica il

50
sapply(yourdataframe, class)

Dove yourdataframe è il nome del frame di dati che stai utilizzando


18

io suggerirei

sapply(foo, typeof)

se sono necessari i tipi effettivi dei vettori nel frame di dati. class()è in qualche modo una bestia diversa.

Se non hai bisogno di ottenere queste informazioni come un vettore (cioè non ti serve per fare qualcos'altro in modo programmatico in seguito), usa semplicemente str(foo).

In entrambi i casi fooverrebbe sostituito con il nome del tuo frame di dati.


7

Passa semplicemente il tuo frame di dati nella seguente funzione:

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")
}

per produrre un diagramma di tutti i tipi di dati nel frame di dati. Per il set di dati dell'iride otteniamo quanto segue:

data_types(iris)

inserisci qui la descrizione dell'immagine


5

Per piccoli frame di dati:

library(tidyverse)

as_tibble(mtcars)

ti dà una stampa del df con tipi di dati

# 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

Per frame di dati di grandi dimensioni:

glimpse(mtcars)

ti dà una visione strutturata dei tipi di dati:

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, ...

Per ottenere un elenco del tipo di dati delle colonne (come detto sopra @Alexandre):

map(mtcars, class)

fornisce un elenco di tipi di dati:

$mpg
[1] "numeric"

$cyl
[1] "numeric"

$disp
[1] "numeric"

$hp
[1] "numeric"

Per modificare il tipo di dati di una colonna:

library(hablar)

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

converte le colonne mpge amin carattere e la colonna carbin intero:

# 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

3

Dal momento che non è stato dichiarato chiaramente, aggiungo solo questo:

Stavo cercando un modo per creare una tabella che contenga il numero di occorrenze di tutti i tipi di dati .

Supponiamo che abbiamo una data.framecon due colonne numeriche e una logica

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

È possibile riepilogare il numero di colonne di ciascun tipo di dati con quello

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

Questo è estremamente utile, se hai molte colonne e vuoi avere una rapida panoramica.

Per dare credito: questa soluzione è stata ispirata dalla risposta di @Cybernetic .


2

Ecco una funzione che fa parte del pacchetto helpRFunctions che restituirà un elenco di tutti i vari tipi di dati nel frame di dati, nonché i nomi delle variabili specifiche associati a quel 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

Potresti quindi fare qualcosa del genere var(my.data[t$numeric]).

Spero sia utile!


1
Vale la pena notare che questo è lapply(your_data, class)un po 'più elaborato per la formattazione.
Gregor Thomas,

1

Se importi il ​​file csv come data.frame (e non matrice), puoi anche usare 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

1

Un'altra opzione sta usando la funzione map del pacchetto purrr.

library(purrr)
map(df,class)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.