使用tidyverse的c_across跨列拼接字符报错的解决求助
解决tidyverse拼接列时的报错问题
嘿,我知道你遇到的这个问题啦,咱们一步步来搞定它!你的需求是把sheet、condition1和condition2按行拼接成新列marker,用/分隔,报错的核心是混淆了str_c参数的用法,咱们来修正它,还有更简单的方案哦!
先重现你的数据
dat <- data.frame(sheet = c("a", "b", "c"), condition1 = c("k", "l", "m"), condition2 = c("x", "y", "z"))
错误原因分析
你原来的代码里,c_across()会返回每行3个元素组成的向量,而str_c(..., sep="/")是用来连接多个不同向量的对应元素(比如str_c(c("a","b"), c("x","y"), sep="/")会得到c("a/x","b/y"))。但你需要的是把单个向量里的所有元素连成一个字符串,这时候得用collapse="/"参数,而不是sep——这就是报错的根源!
方法1:修正你原来的rowwise写法
把sep换成collapse就能解决问题:
library(tidyverse) new_dat <- dat %>% rowwise() %>% mutate(marker = str_c(c_across(c(sheet, starts_with("condition"))), collapse = "/")) %>% ungroup()
方法2:不用rowwise,用pmap按行处理
如果不想用rowwise(),可以用pmap_chr()逐行处理选中的列:
new_dat <- dat %>% mutate(marker = pmap_chr(select(., sheet, starts_with("condition")), ~str_c(c(...), collapse = "/")))
方法3:最简洁的方式——用tidyr::unite
其实tidyverse里有专门做列拼接的函数unite(),这是最省心的写法,直接指定要拼接的列、分隔符,还能保留原列:
new_dat <- dat %>% unite(marker, sheet, starts_with("condition"), sep = "/", remove = FALSE)
这里remove=FALSE表示保留原来的列,如果你想删除原列,可以去掉这个参数(默认是remove=TRUE)。
验证结果
不管用哪种方法,最终输出都完全符合你的预期:
new_dat #> sheet condition1 condition2 marker #> 1 a k x a/k/x #> 2 b l y b/l/y #> 3 c m z c/m/z
内容的提问来源于stack exchange,提问作者deschen
相关产品推荐
相关产品推荐

