我创建了一个dplyr函数来评估总体事件计数。与dplyr :: filter和dplyr :: group_by函数中的变量的显式命名一起使用时,该代码有效。
我需要将该函数应用于24个变量,这些变量是数据帧内的列标题。在这里,它们被称为x。
我用过!据我了解,该变量被评估为字符串而不是列名。
功能
summary_table <- function(x){
assign(paste(x,"sum_tab", sep="_"),
envir = parent.frame(),
value = df %>%
filter(!is.na(!!x)) %>%
group_by(!!x) %>%
summarise(
'Variable name' = paste0(x),
Discharged = sum(admission_status == "Discharged"),
'Re-attended' = sum(!is.na(re_admission_status)),
'Admitted on Re-attendance' = sum(re_admission_status == "Admitted", na.rm = TRUE)))
}
我用过:
sapply(var_names, summary_table)
但是对于列表var_names中的每个变量,它仅输出表的一行
总而言之,我希望有指向正确机制的指针,以将上面编写的函数应用于dplyr管道内的列名列表。
可复制的示例
example <- mtcars %>%
group_by(vs) %>%
summarise(
'6 cylinder' = sum(cyl == 6),
'Large disp' = sum(disp >= 100),
'low gears' = sum(gear <= 4))
})
在此示例中,我们希望将此功能应用于以下列表
cars_var <- c("vm", "am", "carb")
这将为列表中的每一列生成三个表。
答案 0 :(得分:2)
正如@ eipi10所说,自动创建变量通常是不明智的。一个更好的主意是创建一个单独的变量,该变量是数据帧的列表。
让用户使用group_by()
或group_by_at()
自己应用组也更容易,这样您就不必担心他们如何提供变量名称。
编辑2019-05-2
一种方法是将分组变量的名称视为“数据”,并映射它们,以创建由每个分组变量分组的实际数据的副本。
library(dplyr)
library(purrr)
grouping_vars <- c("vs", "am", "carb")
map(grouping_vars, group_by_at, .tbl = mtcars) %>%
map(summarise,
'6 cylinder' = sum(cyl == 6),
'Large disp' = sum(disp >= 100),
'low gears' = sum(gear <= 4))
#> [[1]]
#> # A tibble: 2 x 4
#> vs `6 cylinder` `Large disp` `low gears`
#> <dbl> <int> <int> <int>
#> 1 0 3 18 14
#> 2 1 4 9 13
#>
#> [[2]]
#> # A tibble: 2 x 4
#> am `6 cylinder` `Large disp` `low gears`
#> <dbl> <int> <int> <int>
#> 1 0 4 19 19
#> 2 1 3 8 8
#>
#> [[3]]
#> # A tibble: 6 x 4
#> carb `6 cylinder` `Large disp` `low gears`
#> <dbl> <int> <int> <int>
#> 1 1 2 4 7
#> 2 2 0 8 8
#> 3 3 0 3 3
#> 4 4 4 10 9
#> 5 6 1 1 0
#> 6 8 0 1 0
由reprex package(v0.2.1)于2019-05-02创建
原始答案
这是一个使用dplyr::groups()
来找出哪些变量已分组的函数。然后迭代每个分组变量,汇总,并将结果数据框附加到列表中。
library(dplyr)
margins <- function(.data, ...) {
groups <- dplyr::groups(.data)
n <- length(groups)
out <- vector(mode = "list", length = n)
for (i in rev(seq_len(n))) {
out[[i]] <-
.data %>%
dplyr::group_by(!!groups[[i]]) %>%
dplyr::summarise(...) %>%
dplyr::group_by(!!groups[[i]]) # Reapply the original group
}
out
}
mtcars %>%
group_by(vs, am, carb) %>%
margins('6 cylinder' = sum(cyl == 6),
'Large disp' = sum(disp >= 100),
'low gears' = sum(gear <= 4))
#> [[1]]
#> # A tibble: 2 x 4
#> # Groups: vs [2]
#> vs `6 cylinder` `Large disp` `low gears`
#> <dbl> <int> <int> <int>
#> 1 0 3 18 14
#> 2 1 4 9 13
#>
#> [[2]]
#> # A tibble: 2 x 4
#> # Groups: am [2]
#> am `6 cylinder` `Large disp` `low gears`
#> <dbl> <int> <int> <int>
#> 1 0 4 19 19
#> 2 1 3 8 8
#>
#> [[3]]
#> # A tibble: 6 x 4
#> # Groups: carb [6]
#> carb `6 cylinder` `Large disp` `low gears`
#> <dbl> <int> <int> <int>
#> 1 1 2 4 7
#> 2 2 0 8 8
#> 3 3 0 3 3
#> 4 4 4 10 9
#> 5 6 1 1 0
#> 6 8 0 1 0
由reprex package(v0.2.1.9000)于2019-04-24创建
如果要使用变量名向量分组,可以使用dplyr::group_by_at()
和dplyr::vars()
。
cars_var <- c("vs", "am", "carb")
mtcars %>%
group_by_at(vars(cars_var)) %>%
margins('6 cylinder' = sum(cyl == 6),
'Large disp' = sum(disp >= 100),
'low gears' = sum(gear <= 4))
我是一个名为armgin的小程序包的作者,该程序包实现了此功能以及一些类似的想法。