2011-06-22 4 views
3

Voici le code que j'utilise pour trouver des variables numériques dans une trame de données:R: manière élégante de déterminer les variables numériques dans une trame de données

Data <- iris 
numericvars <- NULL 
for (Var in names(Data)) { 
    if(class(Data[,Var]) == 'integer' | class(Data[,Var]) == 'numeric') { 
     numericvars <- c(numericvars,Var) 
    } 
} 
numericvars 

Est-il un moyen moins loufoque de le faire?

+1

objets qui pousse dans une boucle est un non-non ('numericvars <- c (numericvars, Var)') –

Répondre

14

C'est un assez simple one-liner avec sapply:

sapply(Data, is.numeric) 
# Sepal.Length Sepal.Width Petal.Length Petal.Width  Species 
#   TRUE   TRUE   TRUE   TRUE  FALSE 

# is.numeric should pick up integer columns too 
Data$Species <- as.integer(Data$Species) 
sapply(Data, is.numeric) 
# Sepal.Length Sepal.Width Petal.Length Petal.Width  Species 
#   TRUE   TRUE   TRUE   TRUE   TRUE 
+1

Espèce sort TRUE dans la deuxième tentative. –

+0

@Dirk: ... comme il se doit, selon '? Is.numeric'. –

+0

Endormi au volant ici - j'ai raté que vous avez transformé le facteur en nombre entier. –

3

L'utilisation de sapply() ou lapply() semble logique ici:

sapply(iris, function(x) class(x) %in% c("integer","numeric")) 

qui donne:

> sapply(iris, function(x) class(x) %in% c("integer","numeric")) 
Sepal.Length Sepal.Width Petal.Length Petal.Width  Species 
     TRUE   TRUE   TRUE   TRUE  FALSE 

Worth notant que dans votre boucle, vous développez le numericvars vecteur à chaque itération de la boucle; en R, c'est un gros non-non! Il force R à copier et à étendre le vecteur à chaque fois. Allouer un espace de stockage suffisant avant la main et remplir l'objet; ici que cela signifierait la création numericvars comme

numericvars <- character(length = ncol(iris)) 

puis dans la boucle faisant

nams <- names(iris) 
for(i in seq_len(ncol(iris))) { 
    if(class(iris[, i]) == 'integer' | class(iris[, i]) == 'numeric') { 
     numericvars[i] <- nams[i] 
    } 
} 

Un peu plus de travail, mais beaucoup plus efficace, mais vous ne verrez que quand le nombre d'itérations devient plus grand.

4

Ceci est un peu plus serré:

R> sapply(colnames(iris), function(x) inherits(iris[,x], c("numeric","integer"))) 
Sepal.Length Sepal.Width Petal.Length Petal.Width  Species 
     TRUE   TRUE   TRUE   TRUE  FALSE 
R> 
+0

Oups. Je suppose que j'étais un peu trop tard. –

+0

Y a-t-il une raison de "sonner" sur les noms de colonnes et non sur "data.frame" lui-même? 'spply (iris, hérite, c (" numeric "," integer "))' – Marek

4

Il y a aussi colwise(), numcolwise() et catcolwise() dans plyr. colwise() transforme une fonction qui opère sur un vecteur en une fonction qui fonctionne par colonne sur une trame de données. numcolwise et catcolwise fournissent des versions qui fonctionnent uniquement sur des variables numériques et discrètes respectivement.

library(plyr) 
colwise(is.numeric)(Data) 

> colwise(is.numeric)(Data) 
    Sepal.Length Sepal.Width Petal.Length Petal.Width Species 
1   TRUE  TRUE   TRUE  TRUE FALSE 
Questions connexes