使用dplyr循环创建多个数据框的问题
解决R中循环处理带数字后缀变量的问题
你的代码出错的核心原因是在dplyr中直接用字符串或索引引用列名时,dplyr无法正确识别目标列,以下是修正后的可行方案:
错误原因拆解
- 第一个循环:
var[i]写法完全错误,你没有定义名为var的对象,无法通过索引获取var1/var2列。 - 第二个循环:
group_by(cat, i)里的i会被dplyr当成字面列名(你的数据里没有叫i的列),而不是变量i存储的"var1"/"var2"字符串。
修正方案1:用tidyeval符号解引用(for循环版)
通过sym()将字符串转为dplyr能识别的符号,再用!!解引用:
# 定义目标列名列表 listvar <- c("var1", "var2") for (i in listvar){ # 把字符串列名转为dplyr可识别的符号 target_col <- sym(i) df <- testdata |> group_by(cat, !!target_col) |> summarise(nb = n(), .groups = "drop") |> # .groups参数消除分组警告 rename(var = !!target_col) # 生成对应的数据框名(want1、want2) assign(paste0("want", gsub("var", "", i)), df) }
修正方案2:用.data代词(更简洁)
dplyr的.data代词可以直接通过字符串引用列名,无需额外转换:
listvar <- c("var1", "var2") for (i in listvar){ df <- testdata |> group_by(cat, .data[[i]]) |> summarise(nb = n(), .groups = "drop") |> rename(var = .data[[i]]) assign(paste0("want", gsub("var", "", i)), df) }
更推荐的方案:用列表存储结果(避免assign)
assign会污染全局环境,更规范的做法是把结果存成列表,后续操作更方便:
library(purrr) listvar <- c("var1", "var2") list_results <- map(listvar, function(col){ testdata |> group_by(cat, .data[[col]]) |> summarise(nb = n(), .groups = "drop") |> rename(var = .data[[col]]) }) # 给列表元素命名(对应want1、want2) names(list_results) <- paste0("want", gsub("var", "", listvar)) # 如果一定要生成单独的数据框,用list2env导入全局环境 list2env(list_results, envir = .GlobalEnv)
运行以上代码后,你就能得到和手动编写的want1、want2完全一致的数据框。
内容的提问来源于stack exchange,提问作者user2568648
相关产品推荐
相关产品推荐

