You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用dplyr按条件生成Col3:仅拼接不含±的Name行

问题:使用dplyr根据Name列内容选择性拼接多列生成Col3

假设我们有如下的DataFrame(注意原始数据中存在重复的Col2列,实际读入后列名可能会自动调整为Col2Col2.1,这里我们保持原始描述的列名逻辑):

df <- data.frame(
  Name = c("Wolf_+_", "Fox_-_", "Lezard_-_", "Elephant_-_", "AZ_89809", "Bear_+_", "ZA_08980", "TY_880DD2", "Snail_-_"),
  Col1 = c(NA, NA, NA, NA, "BOL", NA, "LUI", "IOP", NA),
  Col2 = c(NA, NA, NA, NA, "RAL", NA, "OPL", "MPO", NA),
  Col2 = c(NA, NA, NA, NA, "ZIL", NA, "YUI", "UII", NA),
  stringsAsFactors = FALSE
)

需求是:

  • 创建新列Col3
  • 仅对Name中不含+-的行,将NameCol1、两个Col2列的值用|拼接
  • 其余行(Name+-)的Col3仅保留Name的值

当前使用的代码dplyr::mutate(df, Col3 = paste(Name, Col1, Col2, sep='|'))会对所有行进行拼接,不符合需求,期望的结果如下:

Name Col1 Col2 Col2               Col3
1    Wolf_+_ <NA> <NA> <NA>            Wolf_+_
2     Fox_-_ <NA> <NA> <NA>             Fox_-_
3  Lezard_-_ <NA> <NA> <NA>          Lezard_-_
4 Elephant_-_ <NA> <NA> <NA>       Elephant_-_
5   AZ_89809  BOL  RAL  ZIL AZ_89809|BOL|RAL|ZIL
6    Bear_+_ <NA> <NA> <NA>            Bear_+_
7   ZA_08980  LUI  OPL  YUI ZA_08980|LUI|OPL|YUI
8  TY_880DD2  IOP  MPO  UII TY_880DD2|IOP|MPO|UII
9   Snail_-_ <NA> <NA> <NA>           Snail_-_

解决方案

我们可以结合dplyr::case_when()stringr::str_detect()来实现条件逻辑,同时注意处理正则表达式中的特殊字符(+-是正则元字符,需要用fixed()来匹配字面量):

library(dplyr)
library(stringr)

# 注意:如果原始数据的重复Col2列读入后列名为Col2.1,需要将代码中的第二个Col2改为Col2.1
df_result <- df %>%
  mutate(
    Col3 = case_when(
      # 判断Name中是否不包含+或-
      !str_detect(Name, fixed("+")) & !str_detect(Name, fixed("-")) ~ 
        paste(Name, Col1, Col2, Col2, sep = "|"),
      # 其他情况直接返回Name
      TRUE ~ Name
    )
  )

代码说明:

  • str_detect(fixed("+")):由于+-是正则表达式中的特殊元字符,我们用fixed()来指定匹配字面量,避免正则规则干扰匹配结果
  • case_when():这是dplyr中处理多条件分支的工具,第一个分支筛选出Name里既不含+也不含-的行,执行多列拼接;第二个TRUE分支兜底处理所有其他行,直接返回Name的值
  • 拼接列注意事项:原始数据存在重复的Col2列,读入R后列名可能会被自动调整为Col2Col2.1,如果遇到这种情况,记得把paste()里的第二个Col2改成Col2.1

运行上述代码后,就能得到你期望的结果。


内容的提问来源于stack exchange,提问作者Grendel

火山引擎 最新活动