92 votes

Fonction R Apply() sur des colonnes spécifiques du dataframe

Je veux utiliser la fonction apply sur un cadre de données, mais appliquer la fonction uniquement aux 5 dernières colonnes.

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

Cela applique A à toutes les colonnes de y

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

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

wifi[,1:3]+B 

ne fait pas non plus ce que j'attendais/souhaitais.

110voto

leif Points 855

lapply est probablement un meilleur choix que apply ici, car appliquer d'abord coercitive votre data.frame à un tableau, ce qui signifie que toutes les colonnes doivent avoir le même type. En fonction de votre contexte, cela pourrait avoir des conséquences inattendues.

Le modèle est :

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

Le vecteur 'cols' peut être un nom de variable ou un indice. Je préfère utiliser des noms lorsque c'est possible (c'est plus résistant à 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 colonnes :

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

67voto

thelatemail Points 21202

En utilisant un exemple de data.frame et une fonction d'exemple (juste +1 à 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

2voto

Ian Campbell Points 19700

Cette tâche est facilement réalisable avec le dplyr du paquet across fonctionnalité.

Emprunter la structure de données suggéré par lelatemail :

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

Nous pouvons indiquer les colonnes auxquelles nous souhaitons appliquer la fonction soit par index comme ceci :

library(dplyr)
wifi %>% 
   mutate(across(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

Ou par le nom :

wifi %>% 
   mutate(across(X4:X9, 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

1voto

Adam Erickson Points 44

Comme mentionné, vous voulez simplement la norme R apply fonction 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)

Cela met à jour les colonnes 4:9 en place en utilisant la fonction A() fonction. Maintenant, supposons que na.rm est un argument pour A() ce qui devrait être le cas. 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 tout autre argument que vous souhaitez transmettre à votre fonction personnalisée.

0voto

Henrik Mader Points 21

Le moyen le plus simple est d'utiliser la fonction mutate :

dataFunctionUsed <- data %>% 
  mutate(columnToUseFunctionOn = function(oldColumn ...))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X