2017-03-08 3 views
0

J'utilise ddply (à partir du package plyr dans R) dans une fonction de retour à la ligne. Je veux résumer mon ensemble de données en fonction de la valeur d'une variable. Cependant, la fonction de retour à la ligne doit définir pour quelle variable je veux résumer.Utilisation de la fonction ddply à l'intérieur (évaluation non standard)

Sans fonction wrap, je peux prendre l'approche suivante:

require(plyr) 

# Create sample dataframe: 
sample_df <- data.frame(a = rep(1:3, 2), b = rep(3:1, 2), c = rep(c("a", "b"), 3)) 

sample_df 
    a b c 
1 1 3 a 
2 2 2 b 
3 3 1 a 
4 1 3 b 
5 2 2 a 
6 3 1 b 

# Use ddply to summarize the dataframe: 
ddply(sample_df, .(a), summarize, mean = mean(b), var = var(b)) 
    a mean var 
1 1 3 0 
2 2 2 0 
3 3 1 0 

Cependant, en utilisant une fonction d'enveloppement, je ne reçois pas les mêmes résultats:

sumfun <- function(df, v) { # summarize a given dataframe by a given variable, 
    d <- ddply(df, .(v), summarize, mean = mean(b), var = var(b)) 
    return(d) 
} 

# Output using the function: 
sumfun(sample_df, "a") 
    v mean var 
1 a 3 NA 

Pourquoi le comportement de ddply diffèrent lors de l'utilisation dans une fonction? J'ai essayé d'utiliser substitute(v) et eval(substitute(v)) à l'intérieur de la fonction, mais cela ne fait pas de différence.

+1

il suffit de changer 'd <- ddply (df,. (Get (v)), résumer, mean = mean (b), var = var (b))' dans la fonction. –

+0

@RonakShah, vous avez absolument raison! Je n'avais pas pensé que ça pourrait être si facile. Avez-vous une explication pour pourquoi l'appel de 'v' sans' get() 'dans la fonction de retour ne me donnerait pas la valeur de la variable? –

+2

'ddply (df, v, résumer, moyenne = moyenne (b), var = var (b))' Dans 'sumfun' fonctionne, la fonction point' .' définie dans 'plyr' est utilisée pour collecter toutes les variables évaluation ultérieure, voir '? plyr ::.' et [cette vignette] (https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html) – OdeToMyFiddle

Répondre

1

Le paquet plyr et sa fonction ddply sont peu démodé et a évolué dans le dplyr, tidyr et emballages similaires (référencés tidyverse).

# library(tidyverse) 
library(dplyr) 

Ce que vous essayez d'accomplir peut être traduit comme ceci:

sample_df %>% 
    group_by(a) %>% 
    summarize(mean = mean(b), var = var(b)) 
# # A tibble: 3 × 3 
#  a mean var 
# <int> <dbl> <dbl> 
# 1  1  3  0 
# 2  2  2  0 
# 3  3  1  0 

Et, pour l'approche de la fonction:

sumfun <- function(df, v) { 
    df %>% 
     group_by_(v) %>% 
     summarize(mean = mean(b), var = var(b)) 
} 

sumfun(sample_df, 'a') 
# # A tibble: 3 × 3 
#  a mean var 
# <int> <dbl> <dbl> 
# 1  1  3  0 
# 2  2  2  0 
# 3  3  1  0 

Notez la _ finale group_by_ présente en fonction nécessaire faire une évaluation standard. Voir vignette("nse") pour plus de détails.

+0

Je ne suis pas tout à fait passé à l'utilisation le [pipe] (http://r4ds.had.co.nz/pipes.html) et l'opérateur de pipe ('%>%') encore. Cependant, dans ce cas, la lisibilité semble mieux avec le tuyau. –