【问题标题】:Remove rows if string matches X but not Y如果字符串匹配 X 但不匹配 Y,则删除行
【发布时间】:2021-04-17 10:24:27
【问题描述】:

我有以下数据框:

data <- data.frame(id = c(1,2,3,4,5,6),
                   exposure = c("BMI", "BMI etc.", "BMI neuronal", "WHRadjBMI", "WHR", "BF"))
    
    id  exposure
1   1   BMI
2   2   BMI etc.
3   3   BMI neuronal
4   4   WHRadjBMI
5   5   WHR
6   6   BF

我想从该数据框中删除 exposure 列中包含“BMI”但不包含“adj”的所有行,以便我可以将所有与 BMI 相关的行分组到一个称为“BMI”的单一因子级别。实际数据框约为 2500 行 x 50 列。

因此,子集将导致以下数据框,此处第 1、2 和 3 行已被删除,因为它们包含“BMI”但不包含“adj”:

    id  exposure
4   4   WHRadjBMI
5   5   WHR
6   6   BF

然后我可以将包含行的“BMI”但不包含“adj”的行组合成单个因子水平,这样第 1、2 和 3 行将变为:

    id  exposure
1   1   BMI
2   2   BMI
3   3   BMI

我可以按如下方式完成最后一部分:

data$exposure <- "BMI"

【问题讨论】:

    标签: r string filter subset


    【解决方案1】:

    我们可以使用grepl 删除行并将所有BMI 暴露值收敛到一个BMI 值。

    data <- data[!grepl("BMI", data$exposure, fixed=TRUE) ||
                 grepl("adj", data$exposure, fixed=TRUE), ]
    data$exposure <- ifelse(grepl("BMI", data$exposure, fixed=TRUE),
                            "BMI", data$exposure)
    

    【讨论】:

      【解决方案2】:

      使用基础 R + stringr:

      library(stringr)
      data[str_detect(data$exposure, 'BMI') & str_detect(data$exposure, 'adj', negate=TRUE),]
      

      您有两个逻辑条件与逻辑 AND 组合:data$exposure 包含 BMIdata$exposure 不包含 adj

      【讨论】:

        【解决方案3】:

        我不确定这是不是你想要的

        within(
          data,
          exposure <- gsub("^(?<=BMI).*", "", exposure, perl = TRUE)
        )
        

        给了

          id  exposure
        1  1       BMI
        2  2       BMI
        3  3       BMI
        4  4 WHRadjBMI
        5  5       WHR
        6  6        BF
        

        【讨论】:

        • 这完全符合我的要求(虽然我不太确定如何?)。我认为它只是将“BMI”的每个实例后跟任何字符串更改为“BMI”。因此,它不会改变字符串后面出现“BMI”的任何内容?
        • @matt 是的,没错。替换就像模式匹配一​​样发生。
        • 请注意,这也会将值 WHRBMIadj 替换为 WHRBMI,根据 OP 的规则,这不应该发生。
        • @TimBiegeleisen 感谢您的提醒。我错过了^,但现在修复它。希望它能解决问题。
        【解决方案4】:

        这行得通吗?

        library(tidyverse)
        
        filtered_data <- data %>%
          filter(!stringr::str_detect(exposure, "^BMI")) %>%
          mutate(exposure = "BMI")
        
        filtered_data
          id exposure
        1  4      BMI
        2  5      BMI
        3  6      BMI
        

        【讨论】:

          猜你喜欢
          • 2022-10-15
          • 1970-01-01
          • 2019-12-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-12
          • 2013-03-10
          相关资源
          最近更新 更多