如何在dplyr的mutate(across)中用字符向量指定列名
解决方案:用字符向量指定列名实现
across批量处理 核心问题解决
要让字符向量ok.netroles实现和直接写列名(netrole1, netrole2)一样的效果,只需在across()中用all_of()包裹字符向量即可,语法为:
mutate(across(all_of(ok.netroles), ~你的处理逻辑))
修正你的代码错误
你的代码存在两个关键问题:
across()必须在mutate()、summarize()等数据掩码动词内部使用,不能直接放在管道流中;- 计算
nr.sum时逻辑错误:across()返回多列结果,不能赋值给单个标量变量,且不能用未定义的nr.sum作为分母。
修正后的完整代码
# 定义列名向量 fes <- c("black", "latinx", "asian", "othermx", "noeths", "prefno") ok.netroles <- c("netrole1", "netrole3", "netrole4") # 数据处理流程 fes.sums <- unidata %>% # 同时汇总种族列和netrole列的计数 summarize( across(all_of(fes), ~sum(.x, na.rm = TRUE)), across(all_of(ok.netroles), ~sum(.x, na.rm = TRUE)) ) %>% # 计算总人数(种族列的总和,每个受访者对应一个种族) mutate(eth.sum = rowSums(pick(all_of(fes)), na.rm = TRUE)) %>% # 计算种族分类的占比(百分比) mutate(across(all_of(fes), ~100 * .x / eth.sum)) %>% # 计算netrole分类的占比(百分比) mutate(across(all_of(ok.netroles), ~100 * .x / eth.sum))
代码解释
all_of(ok.netroles):将字符向量转换为across()可识别的列选择器,完全等价于直接写列名;pick(all_of(fes)):批量选择种族列,再用rowSums()计算总人数,避免手动罗列所有种族列名,更灵活;- 分两次
mutate处理种族和netrole列,逻辑更清晰,也可合并为一个mutate。
错误原因说明
across()使用位置错误:报错Must only be used inside data-masking verbs是因为你把across()直接放在管道中,没有包裹在mutate()/summarize()内部;- 字符向量求和错误:报错
invalid 'type' (character) of argument是因为直接对字符向量ok.netroles求和,应该用pick(all_of(ok.netroles))选择对应列后再计算。
测试样本数据运行结果
用你提供的样本数据测试,运行上述代码后会得到各分类的占比结果,例如:
# A tibble: 1 × 9 black latinx asian othermx noeths prefno netrole1 netrole3 eth.sum <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 12.9 0 60.4 0 0 0 0 60.4 101
内容的提问来源于stack exchange,提问作者Stuart
相关产品推荐
相关产品推荐

