通过dplyr循环创建多个数据框
对于我的数据中一系列具有数字后缀的变量,例如var1、var2、…、varN,我想对它们执行相同的操作,并将每个结果存储在一个单独的数据框中。
我已经尝试了两种使用for的循环形式,但每种方法都会导致错误。
下面是一个最小工作示例(MWE):
# Dummy data
testdata <- data.frame(cat=c("A","A","B","B"),
var1=c(1:4),
var2=c(5:8))
# Desired outcome - a series of df
want1 <- testdata |>
group_by(cat, var1) |>
summarise(nb=n()) |>
rename(var = var1)
want2 <- testdata |>
group_by(cat, var2) |>
summarise(nb=n()) |>
rename(var = var2)
# Tried solutions - which give errors
for (i in 1:2){
df <- testdata |>
group_by(cat, var[i]) |>
summarise(nb=n()) |>
rename(var = var[i])
assign(paste("want", i, sep=""), df)
}
listvar <- c("var1", "var2")
for (i in listvar){
df <- testdata |>
group_by(cat, i) |>
summarise(nb=n()) |>
rename(var = i)
assign(paste("want", i, sep=""), df)
}
解决方案
对我来说,完成你想要的操作的最整洁方式,是把数据转换成长格式(long format):
testdata %>%
pivot_longer(c(var1, var2), names_to = "var") %>%
group_by(cat, var) %>%
summarise(nb = n(), .groups = "drop")
# A tibble: 4 × 3
cat var nb
<chr> <chr> <int>
1 A var1 2
2 A var2 2
3 B var1 2
4 B var2 2
但这会把你所有的汇总结果放进一个单独的 tibble 中。
要在一个 list 中将其拆分为单独的 tibble,你可以添加对 group_map 或 group_split 的调用:
testdata %>%
pivot_longer(c(var1, var2), names_to = "var") %>%
group_by(cat, var) %>%
summarise(nb = n(), .groups = "drop_last") %>%
group_map(\(.x, .y) .x, .keep = TRUE)
[[1]]
# A tibble: 2 × 3
cat var nb
<chr> <chr> <int>
1 A var1 2
2 A var2 2
[[2]]
# A tibble: 2 × 3
cat var nb
<chr> <chr> <int>
1 B var1 2
2 B var2 2
testdata %>%
pivot_longer(c(var1, var2), names_to = "var") %>%
group_by(cat, var) %>%
summarise(nb = n(), .groups = "drop_last") %>%
group_split()
<list_of<
tbl_df<
cat : character
var: character
nb : integer
>
>[2]>
[[1]]
# A tibble: 2 × 3
cat var nb
<chr> <chr> <int>
1 A var1 2
2 A var2 2
[[2]]
# A tibble: 2 × 3
cat var nb
<chr> <chr> <int>
1 B var1 2
2 B var2 2
从那里开始,如果你确实想把 tibble 的 list 拆分成独立的对象,那也只是简单的操作。
这三种选项在变量数量和类别数量方面都具有鲁棒性,或者很容易实现鲁棒性。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。