2017-03-08 103 views
0

我在包装函数中使用ddply(来自包的R)。我想基于变量的值来总结我的数据集。但是,wrap函数必须定义我想要汇总的变量。在函数内部使用ddply(非标准评估)

如果没有包装的功能,我可以采取以下方法:

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 

但是,使用保鲜功能,我没有得到相同的结果:

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 

为什么行为ddply在函数中使用它有什么不同?我曾尝试在函数内部使用substitute(v)eval(substitute(v)),但它没有区别。

+1

只是在函数中变成'd < - ddply(df,。(get(v)),summarize,mean = mean(b),var = var(b))''。 –

+0

@RonakShah,你是对的!我没有想到它可能如此简单。你有没有解释为什么在函数内部调用没有'get()'的'v'不会让我获得变量的值? –

+2

'sumpun'内的'ddply(df,v,summary,mean = mean(b),var = var(b))作用于'plyr'中定义的dot'.'函数用于收集所有引用变量后来的评估,请参阅'?plyr ::。'和[这个vignette](https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html) – OdeToMyFiddle

回答

1

plyr包及其ddply功能是一种过时的,演变成dplyrtidyr和类似的包(如tidyverse参考)。

# library(tidyverse) 
library(dplyr) 

你正在尝试完成可翻译如下:

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 

而且,对于功能的方法:

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 

注意在group_by_存在的功能最终_需要做标准评估。有关详细信息,请参阅vignette("nse")

+0

我还没有完全过渡到使用还有[pipe](http://r4ds.had.co.nz/pipes.html)和管道操作符('%>%')。但是,在这种情况下,管道的可读性似乎更好。 –