如何使用字符向量作为参数逐行应用R语言自定义函数?
问题描述
现有如下定义的tibble和字符向量:
ref_tables <- tibble(`col 1` = letters[1:5], `col 2` = letters[6:10], `col 3` = letters[11:15]) # 输出如下: # `col 1` `col 2` `col 3` # <chr> <chr> <chr> # 1 a f k # 2 b g l # 3 c h m # 4 d i n # 5 e j o index_selection <- c("col 1", "col 2", "col 3")
自定义函数f用于将输入向量拼接成字符串:
f <- function(x) { return(paste(x, collapse = " ")) }
当显式用反引号指定列名时,能得到预期结果:
d <- ref_tables %>% rowwise() %>% mutate(dfs = list(f(c(`col 1`, `col 2`, `col 3`)))) # d$dfs[1] 返回 "a f k"
但使用字符向量index_selection时,得到的是列名而非对应值:
d <- ref_tables %>% rowwise() %>% mutate(dfs = list(f(index_selection))) # d$dfs[1] 返回 "col 1 col 2 col 3"
需要解决如何通过字符向量指定列,实现逐行应用函数的需求。
解决方案
方法1:使用pick() + c_across()(tidyverse 1.3.0+推荐)
pick()可以直接接收字符向量选择列,c_across()在rowwise()上下文里会将选中的列按行合并为向量,完美适配需求:
d <- ref_tables %>% rowwise() %>% mutate(dfs = list(f(c_across(all_of(index_selection))))) # 验证结果 d$dfs[1] # 返回 "a f k"
方法2:使用syms() + !!!解引用字符向量
将字符向量转换为符号列表,再通过!!!展开,就能引用到对应列的值:
d <- ref_tables %>% rowwise() %>% mutate(dfs = list(f(c(!!!syms(index_selection))))) # 验证结果 d$dfs[1] # 返回 "a f k"
方法3:不用rowwise(),用pmap()实现高效逐行处理
如果数据量较大,rowwise()效率较低,可使用pmap()直接处理选中的列:
d <- ref_tables %>% mutate(dfs = pmap(select(., all_of(index_selection)), ~f(c(...)))) # 验证结果 d$dfs[1] # 返回 "a f k"
内容的提问来源于stack exchange,提问作者user2962397
相关产品推荐
相关产品推荐

