web-dev-qa-db-fra.com

R Fonction Apply () sur des colonnes de données spécifiques

Je souhaite utiliser la fonction apply sur une image de données, mais n'applique cette fonction qu'aux 5 dernières colonnes.

B<- by(wifi,(wifi$Room),FUN=function(y){apply(y, 2, A)})

Ceci s'applique à toutes les colonnes de y

B<- by(wifi,(wifi$Room),FUN=function(y){apply(y[4:9], 2, A)})

Ceci s'applique uniquement aux colonnes 4 à 9 de y, mais le rendement total de B supprime les 3 premières colonnes ... Je les veux toujours, je ne veux pas que A leur soit appliqué.

wifi[,1:3]+B 

aussi ne fait pas ce que je pensais/voulais.

58
skmathur

Utilisation d'un exemple data.frame et d'une fonction exemple (juste +1 pour toutes les valeurs)

A <- function(x) x + 1
wifi <- data.frame(replicate(9,1:4))
wifi

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  1  1  1  1  1  1
#2  2  2  2  2  2  2  2  2  2
#3  3  3  3  3  3  3  3  3  3
#4  4  4  4  4  4  4  4  4  4

data.frame(wifi[1:3], apply(wifi[4:9],2, A) )
#or
cbind(wifi[1:3], apply(wifi[4:9],2, A) )

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5

Ou même:

data.frame(wifi[1:3], lapply(wifi[4:9], A) )
#or
cbind(wifi[1:3], lapply(wifi[4:9], A) )

#  X1 X2 X3 X4 X5 X6 X7 X8 X9
#1  1  1  1  2  2  2  2  2  2
#2  2  2  2  3  3  3  3  3  3
#3  3  3  3  4  4  4  4  4  4
#4  4  4  4  5  5  5  5  5  5
50
thelatemail

lapply est probablement un meilleur choix que apply ici, car appliquer en premier force votre data.frame dans un tableau, ce qui signifie que toutes les colonnes doivent avoir le même type. Selon votre contexte, cela pourrait avoir des conséquences inattendues.

Le motif est:

df[cols] <- lapply(df[cols], FUN)

Le vecteur 'cols' peut être un nom de variable ou un index. Je préfère utiliser des noms chaque fois que cela est possible (c'est robuste pour la réorganisation des colonnes). Donc, dans votre cas, cela pourrait être:

wifi[4:9] <- lapply(wifi[4:9], A)

Un exemple d'utilisation des noms de colonne:

wifi <- data.frame(A=1:4, B=runif(4), C=5:9)
wifi[c("B", "C")] <- lapply(wifi[c("B", "C")], function(x) -1 * x)
59
leif

Comme mentionné, vous souhaitez simplement que la fonction standard R apply soit appliquée aux colonnes (MARGIN=2):

wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A)

Ou, pour faire court:

wifi[,4:9] <- apply(wifi[,4:9], 2, A)

Ceci met à jour les colonnes 4: 9 sur place à l'aide de la fonction A(). Supposons maintenant que na.rm est un argument de A(), ce qu'il devrait probablement être. Nous pouvons passer na.rm=T pour supprimer les valeurs NA du calcul de la manière suivante:

wifi[,4:9] <- apply(wifi[,4:9], MARGIN=2, FUN=A, na.rm=T)

Il en va de même pour tous les autres arguments que vous souhaitez transmettre à votre fonction personnalisée.

0
Adam Erickson

Je pense que ce que vous voulez est mapply. Vous pouvez appliquer la fonction à toutes les colonnes, puis simplement supprimer les colonnes que vous ne voulez pas. Cependant, si vous appliquez différentes fonctions à différentes colonnes, il semble probable que ce que vous voulez est mutate , à partir du paquet dplyr. 

0
Mox