【问题标题】:Dynamic group_by argument based on a list, R, for loop/function基于列表 R 的动态 group_by 参数 for 循环/函数
【发布时间】:2017-10-14 04:16:27
【问题描述】:

使用dplyr

这是我的数据集:

Class   Time    Honors  Grade    Total Students
Math    AM      Yes     PassFail    23
English AM      No      Letter      31
Science AM      Yes     Letter      22
Gym     AM      No      PassFail    26
Math    PM      Yes     PassFail    19
English PM      No      Letter      23
Science PM      Yes     Letter      24
Gym     PM      No      PassFail    13
Math    AM      Yes     PassFail    24
English AM      Yes     Letter      27
Science AM      No      Letter      28
Math    PM      No      Letter      21
English PM      Yes     PassFail    23
Science PM      No      PassFail    22

我想运行四个查询,四个越来越具体的答案。第一个查询将有一个 group_by 参数,后两个 group_by 参数,三个用于第三个,依此类推。

#query 1 
df %>%
  group_by(Class) %>%
  summarise(NewValue = mean(`Total Students`))

#results
    Class NewValue
    <chr>    <dbl>
1 English    26.00
2     Gym    19.50
3    Math    21.75
4 Science    24.0

第二个查询是相同的基本计算,但多了一个 group_by 参数。

#query2
df %>%
  group_by(Class, Time) %>%
  summarise(NewValue = mean(`Total Students`))

#results
    Class  Time NewValue
    <chr> <chr>    <dbl>
1 English    AM     29.0
2 English    PM     23.0
3     Gym    AM     26.0
4     Gym    PM     13.0
5    Math    AM     23.5
6    Math    PM     20.0
7 Science    AM     25.0
8 Science    PM     23.0

模式继续#query3将是

 df %>%
  group_by(Class, Time, Honors) %>%
  summarise(NewValue = mean(`Total Students`))

#query4 将是

df %>%
  group_by(Class, Time, Honors, Grade) %>%
  summarise(NewValue = mean(`Total Students`))

问题:

有没有办法编写一个查询并使用 for 循环在 group_by 参数中合并不断增加的详细级别?

例如,下面的伪代码不起作用;我希望有一个类似的解决方案:

resultsarray <- data.frame()
Groupbysteps <- c( "Class", 
                   "Class, Time", 
                   "Class, Time, Honors", 
                   "Class, Time, Honors, Grade")

for (i in Groupbysteps) {
      resultsarray <- df%>%
                       group_by( Groupbysteps) %>%
                       summarise(NewValue = mean(`Total Students`))

 all <- rbind.fill(all, resultsarray)
}

【问题讨论】:

  • 查询有不同的列。您想为缺少的列填充什么?你能显示你想要的输出吗?
  • @Psidom NAs​​ 是需要的。我将下面的答案标记为正确。结果是 NAs​​

标签: r loops dplyr


【解决方案1】:

这可以工作。

Groupbysteps <- c( "Class", "Time", "Honors", "Grade")

for (i in 1 : length(Groupbysteps)) {
      resultsarray <- df%>%
                       group_by(.dots = Groupbysteps[1 : i]) %>%
                       summarise(NewValue = mean(`Total Students`))

 all <- rbind.fill(all, resultsarray)
}

以下作品:

示例数据集

df <- iris[1:20, ]
colnames(df) <- c( "Class", "Time", "Honors", "Grade", "Total Students")
df[, 1] <- as.factor(sample(c("a", "b"), rep=T)) 
df[, 2] <- as.factor(sample(c("a", "b"), rep=T)) 
df[, 3] <- as.factor(sample(c("a", "b"), rep=T)) 
df[, 4] <- as.factor(sample(c("a", "b"), rep=T)) 
df[, 5] <- rnorm(20)

代码:

Groupbysteps <- c( "Class", "Time", "Honors", "Grade")
resultsarray <- data.frame()

for (i in 1 : length(Groupbysteps)) {

  resultsarray <- df %>%
    group_by(.dots = Groupbysteps[1 : i]) %>%
    summarise(NewValue = mean(`Total Students`))

  all <- rbind.fill(all, resultsarray)
}

【讨论】:

  • 这很好用。对于其他正在查看此答案的人。这使用plyrdplyr,除了@Disco Superfly 解释的内容之外,您还必须运行all &lt;- data.frame()
【解决方案2】:

如图所示在 rlang 中尝试syms

library(dplyr)
library(rlang)

L <- lapply(1:4, function(i) df %>% 
                               group_by(!!!syms(names(df)[1:i])) %>% 
                               summarize(newValue = mean(Total_Students))
)

给出一个列表 L 的 4 个数据框,其列名是:

> lapply(L, names)
[[1]]
[1] "Class"    "newValue"

[[2]]
[1] "Class"    "Time"     "newValue"

[[3]]
[1] "Class"    "Time"     "Honors"   "newValue"

[[4]]
[1] "Class"    "Time"     "Honors"   "Grade"    "newValue"

【讨论】:

  • 那个输出很有趣,我假设有一种方法可以轻松转换为表格?
  • 我假设由于您已经在问题本身中展示了如何做到这一点,因此没有必要在答案中重复它,而只是为了完成它会是rbind.fill(L)
猜你喜欢
  • 2017-06-04
  • 2013-04-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 2019-09-03
  • 2019-01-12
  • 2016-09-21
相关资源
最近更新 更多