R语言使用存储列名的向量paste多列生成data.frame新列
问题说明
现有测试数据框:
df <- data.frame( a = c("A", "B"), b = c("C", "D"), c = c("E, F", "G, H")) df # a b c # 1 A C E, F # 2 B D G, H
需要新增new列,按行拼接列值,规则为:每行取a、b列值用, 拼接,加: 后拼接c列对应值,目标输出如下:
# a b c new # 1 A C E, F A, C: E, F # 2 B D G, H B, D: G, H
约束条件:必须使用预先定义的列名变量,禁止硬编码列名,预设变量为:
cols <- c("a", "b") single <- "c"
原错误写法直接取整列子集拼接,导致所有行的前缀都是两列全部值拼接的结果,输出不符合预期:
df <- df %>% mutate( new = paste0(paste0(df[,cols], collapse = ", "), ": ", df[,single])) # 错误输出 # a b c new # 1 A C E, F c("A", "B"), c("C", "D"): E, F # 2 B D G, H c("A", "B"), c("C", "D"): G, H
正确实现方法
方法1:按行处理 + 列名准确定位(推荐)
使用rowwise()将数据框切换为按行处理模式,配合c_across()取当前行指定列的值,用all_of()传入预设的多列名变量,单列用.data[[ ]]代词传入,避免整列取值的问题:
library(dplyr) df <- df %>% rowwise() %>% mutate( new = paste( paste(c_across(all_of(cols)), collapse = ", "), .data[[single]], sep = ": " ) ) %>% ungroup()
运行后输出完全匹配目标结果:
# A tibble: 2 × 4 a b c new <chr> <chr> <chr> <chr> 1 A C E, F A, C: E, F 2 B D G, H B, D: G, H
说明:all_of()是tidyverse官方推荐的、用于传入外部列名字符向量的标准写法,可避免编程模式下的列名匹配告警;.data是dplyr提供的当前数据代词,.data[[single]]只会取当前行对应列的值,不会出现直接调用df[,single]时的整列复用问题。
方法2:unite多列拼接 + 二次组合
如果习惯用tidyr::unite处理多列合并,也可以先生成临时拼接列再组合最终结果:
library(dplyr) library(tidyr) df <- df %>% unite("temp_prefix", all_of(cols), sep = ", ", remove = FALSE) %>% mutate(new = paste(temp_prefix, .data[[single]], sep = ": ")) %>% select(-temp_prefix)
最终输出和方法1完全一致。
内容的提问来源于stack exchange,提问作者karuno
相关产品推荐
相关产品推荐

