5 votes

Parcourir une fonction à travers différentes colonnes d'un data.frame correspondant à un motif dans les noms des colonnes

Je veux itérer une fonction à travers différentes colonnes (avec un motif commun dans les noms de colonnes) d'un data.frame. Pour sous-ensemble le data.frame, j'utilise ce code qui fonctionne :

df[,grep("abc", colnames(df))]

mais je ne sais pas comment appliquer ma fonction f(x) à toutes les colonnes qui correspondent à ce motif, que ce soit en utilisant une boucle for ou la fonction lapply.

la fonction que j'utilise est :

compress= function(x) {
  aggregate(df[,x,drop=FALSE],
        list(hour = with(df,paste(dates(Time),
                                         sprintf("%d:00:00",hours(Time))))),
        sum,na.rm=TRUE)
}

où df (le data frame) et Time pourraient être définis en tant que variables eux-mêmes mais pour le moment je n'ai pas besoin de le faire.

Merci Giulia

6voto

Simon O'Hanlon Points 27680

Vous l'avez essentiellement obtenu. Utilisez simplement apply sur les colonnes de vos données subsetted pour appliquer la fonction f aux colonnes (le 2 dans le deuxième argument de apply indique les colonnes, par opposition au 1 qui indique d'appliquer sur les lignes) :

apply( df[,grep("abc", colnames(df))] , 2 , f )

Ou si vous ne voulez pas coercer votre df en une matrix (ce qui se produira avec apply), vous pouvez utiliser lapply comme vous le suggérez de manière similaire...

lapply( df[,grep("abc", colnames(df))] , f )

La valeur de retour de lapply sera une liste, avec un élément pour chaque colonne. Vous pouvez retransformer cela en un data.frame en enveloppant l'appel de lapply avec un data.frame, par exemple data.frame( lapply(...) )

Exemple

# Cette fonction multiplie simplement son argument par 2
f <- function(x) x * 2

df <- data.frame( AB = runif(5) , AC = runif(5) , BB = runif(5) )

apply( df[,grep("A", colnames(df))] , 2 , f )
#            AB        AC
#[1,] 0.4130628 1.3302304
#[2,] 0.2550633 0.1896813
#[3,] 1.5066157 0.7679393
#[4,] 1.7900907 0.5487673
#[5,] 0.7489256 1.6292801

data.frame( lapply( df[,grep("A", colnames(df))] , f ) )
#         AB        AC
#1 0.4130628 1.3302304
#2 0.2550633 0.1896813
#3 1.5066157 0.7679393
#4 1.7900907 0.5487673
#5 0.7489256 1.6292801

# Notez la différence importante entre les deux méthodes...
class( data.frame( lapply( df[,grep("A", colnames(df))] , f ) ) )
#[1] "data.frame"
class( apply( df[,grep("A", colnames(df))] , 2 , f ) )
#[1] "matrix"

Deuxième édition

Pour la fonction d'exemple que vous voulez exécuter, il pourrait être plus facile de la réécrire en tant qu'une fonction qui prend le df en entrée et un vecteur de noms de colonnes sur lesquels vous voulez opérer. Dans cet exemple, la fonction renvoie une liste, chaque élément de cette liste contenant un data.frame agrégé :

compress= function( df , x ) {
  lapply( x , function(x){
  aggregate(df[,x,drop=FALSE],
        list(hour = with(df,paste(dates(Time),
                                         sprintf("%d:00:00",hours(Time))))),
        sum,na.rm=TRUE)
    }
  )
}

Pour exécuter la fonction, vous n'avez qu'à l'appeler, en lui passant le data.frame et un vecteur de noms de colonnes...

compress( df , names(df)[ grep("abc", names(df) ) ] )

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