通过dplyr循环创建多个数据框

编程语言 2026-07-08

对于我的数据中一系列具有数字后缀的变量,例如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_mapgroup_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

从那里开始,如果你确实想把 tibblelist 拆分成独立的对象,那也只是简单的操作。

这三种选项在变量数量和类别数量方面都具有鲁棒性,或者很容易实现鲁棒性。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章