首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在summarize()中使用变量作为参数

在summarize()中使用变量作为参数
EN

Stack Overflow用户
提问于 2018-03-20 03:50:07
回答 1查看 2.7K关注 0票数 1

我希望将用户输入变量传递给group_by()和summarize()函数。

数据帧和代码的直接示例如下所示。这里我对列名进行了“硬编码”。

代码语言:javascript
复制
library(dplyr)
df <- data.frame('Category' = c('a','c','a','a','b','a','b','b'), 
             'Amt' = c(100,300,200,400,500,1000,350,250), 
             'Flag' = c(0,1,1,1,0,1,1,0))
rowCount <- nrow(df)
totalAmt <- sum(df$Amt)
g <- group_by(df, Category)
summ <- summarize(g, Count = n(), CountPercentage = n()*100/rowCount, TotalAmt = sum(Amt), AmtPercentage = sum(Amt)*100/totalAmt, FlagSum = sum(Flag))
summ

输出如下所示

在我正在开发的应用程序中,数据帧和列名将是用户定义的。我将读取.csv文件中的文件名、要分组的列和要汇总的列。

我进行了广泛的搜索,在花费了大量的时间阅读和实验之后,我找到了下面所示的解决方案,它对我来说是有效的。我没有使用管道来使步骤更清晰。

代码语言:javascript
复制
#The data frame df is read from the .csv file name
#Variables read from the Excel file
groupby <- 'Category'
sumBy1 <- 'Amt'
sumBy2 <- 'Flag'

rowCount <- nrow(df)
totalAmt <- sum(df[sumBy1])

g <- group_by_(df, groupby) #group by variable  #grouping

summcount <- summarize(g, Count = n(), CountPercentage = n()*100/rowCount) #summarize counts  #piece 1

summamt <- summarize_at(g, .vars = sumBy1, .funs=sum) #summarize by first variable
summamt <- summamt[-1] #remove first column to remove duplicate column
summamt$AmtPercentage <- summamt[sumBy1]*100/totalAmt  #piece 2

summflag <- summarize_at(g, .vars = sumBy2, .funs=sum) #summarize by second variable
summflag <- summflag[-1] #remove first column to remove duplicate column #piece 3

summ <- cbind(summcount, summamt, summflag)  #combine dataframes
summ

结果和上面的一样。正如您所看到的,我正在逐个创建最终的数据帧,然后绑定它们。代码很难看。另外,如何在此语法中定义列标题?我确实考虑过summarize_all(),但这需要创建数据帧的子集。我已经阅读了以下问题,它们对我不起作用

Passing arguments to dplyr summarize function

Summarizing data in table by group for each variable in r

你能推荐一种更简单、更优雅的方法吗?

上面我已经“硬编码”了两种类型的摘要,即。计数和求和。为了增加另一个级别的复杂性,如果用户还想定义摘要的类型(即,和、均值、计数等)必需的?在Excel文件中,我可以捕获针对每个变量所需的汇总类型。

谢谢你的建议。

EN

回答 1

Stack Overflow用户

发布于 2018-03-20 04:30:09

这听起来像是超人的工作!或者至少是准引语。

您希望使用!!操作符插入变量。

你可以这样做

代码语言:javascript
复制
# Make a variable symbol from strings
make_var <- function(prefix, var, suffix) 
    as.symbol(paste0(prefix, var, suffix))
calc_summary <- function(df, groupby, sumBy1, sumBy2) {
    totalSumBy1      <- make_var("Total", sumBy1, "")
    sumBy1Percentage <- make_var("", sumBy1, "Percentage")
    sumBy1           <- make_var("", sumBy1, "")
    sumBy2Sum        <- make_var("", sumBy2, "Sum")
    sumBy2           <- make_var("", sumBy2, "")

    group_by_(df, groupby) %>%
        summarize(Count = n(), 
                  CountPercentage = n()*100/rowCount,
                  !!totalSumBy1 := sum(!!sumBy1),
                  !!sumBy2Sum := sum(!!sumBy2)) %>%
        mutate(CountPercentage = Count/sum(Count),
               !!sumBy1Percentage := 100 * !!totalSumBy1 / sum(!!totalSumBy1)) 
}

当您使用!!时,您插入的是一个变量的值,所以这就是您可以参数化给定给dplyr函数的表达式的方式。您需要它们作为符号,这就是我使用make_var函数的原因。它可以更优雅地完成,但这将给出您在示例中使用的变量。

注意,当我们赋值的变量是动态的时,我们必须使用:=赋值而不是=赋值。否则,解析器会报错。

您可以按如下方式使用此函数:

代码语言:javascript
复制
> df %>% calc_summary("Category", "Amt", "Flag")
# A tibble: 3 x 6
  Category Count CountPercentage TotalAmt FlagSum AmtPercentage
  <fct>    <int>           <dbl>    <dbl>   <dbl>         <dbl>
1 a            4           0.500    1700.      3.         54.8 
2 b            3           0.375    1100.      1.         35.5 
3 c            1           0.125     300.      1.          9.68

列的顺序与示例中的不同,但您可以使用select解决这个问题。我通过在总结之后将百分比计算移动到mutate中,对百分比计算进行了一些清理。它不再需要rowCount变量。如果您愿意,可以很容易地使用该变量并避免mutate调用。然后,您还可以在summarise调用中按您想要的顺序获取列。

无论如何,重要的一点是,您需要在这里使用bang-bang运算符。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49371260

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档