分享
三行代码  ›  专栏  ›  技术社区  ›  amisos55

基于r中两个条件的重编码 - recoding based on two condtions in r

  •  1
  • amisos55  · 技术社区  · 1 周前

    我有一个数据集示例如下:

    data <- as.data.frame(c("A","B","C","X1_theta","X2_theta","AB_theta","BC_theta","CD_theta"))
    colnames(data) <- "category"
    > data
      category
    1        A
    2        B
    3        C
    4 X1_theta
    5 X2_theta
    6 AB_theta
    7 BC_theta
    8 CD_theta
    

    当类别(变量)中包含“theta”时,我试图生成一个逻辑变量。但是,当单元格值包含 "X1" "X2" 是的。

    以下是我所做的:

    data$logic <- str_detect(data$category, "theta")
    > data
      category logic
    1        A FALSE
    2        B FALSE
    3        C FALSE
    4 X1_theta  TRUE
    5 X2_theta  TRUE
    6 AB_theta  TRUE
    7 BC_theta  TRUE
    8 CD_theta  TRUE
    

    这里,所有具有“theta”的单元格值都具有“true”的逻辑值。

    然后,我在下面写了这个,当单元格值中有“x”时,就指定“false”。

    data$logic <- ifelse(grepl("X", data$category), "FALSE", "TRUE")
    > data
      category logic
    1        A  TRUE
    2        B  TRUE
    3        C  TRUE
    4 X1_theta FALSE
    5 X2_theta FALSE
    6 AB_theta  TRUE
    7 BC_theta  TRUE
    8 CD_theta  TRUE
    

    但是,这当然是对之前的应用程序的过度保护

    我想得到的是结合两个条件:

    > data
      category logic
    1        A FALSE
    2        B FALSE
    3        C FALSE
    4 X1_theta FALSE
    5 X2_theta FALSE
    6 AB_theta  TRUE
    7 BC_theta  TRUE
    8 CD_theta  TRUE
    

    有什么想法吗? 谢谢

    1 回复  |  直到 1 周前
        1
  •  2
  •   akrun    1 周前

    我们可以创建“逻辑”,方法是在末尾检测子字符串“theta”,而不使用“x”( [^X] )作为开始( ^ )性格

    libary(dplyr)
    library(stringr)
    library(tidyr)
    data %>%
        mutate(logic = str_detect(category, "^[^X].*theta$"))
    

    如果我们需要根据条件将列拆分为单独的列

    data %>%
       mutate(logic = str_detect(category, "^[^X].*theta$"),
              category = case_when(logic ~ str_replace(category, "_", ","),
               TRUE ~ as.character(category))) %>%
       separate(category, into = c("split1", "split2"), sep= ",", remove = FALSE)
    #  category   split1 split2 logic
    #1        A        A   <NA> FALSE
    #2        B        B   <NA> FALSE
    #3        C        C   <NA> FALSE
    #4 X1_theta X1_theta   <NA> FALSE
    #5 X2_theta X2_theta   <NA> FALSE
    #6 AB,theta       AB  theta  TRUE
    #7 BC,theta       BC  theta  TRUE
    #8 CD,theta       CD  theta  TRUE
    

    或在 base R

    data$logic <- with(data, grepl("^[^X].*theta$", category))
    

    另一个选择是有两个 grepl 条件语句

    data$logic <- with(data, grepl("theta$", category) & !grepl("^X\\d+", category))
    data$logic
    #[1] FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE
    
        2
  •  0
  •   lemonlin    1 周前

    不是世界上最干净的(因为它添加了2个不必要的col),但它完成了任务:

    data <- as.data.frame(c("A","B","C","X1_theta","X2_theta","AB_theta","BC_theta","CD_theta"))
    colnames(data) <- "category"
    
    data$logic1 <- ifelse(grepl('X',data$category), FALSE, TRUE)
    data$logic2 <- ifelse(grepl('theta',data$category),TRUE, FALSE)
    data$logic <- ifelse((data$logic1 == TRUE & data$logic2 == TRUE), TRUE, FALSE)
    print(data)
    

    我想你也可以删除逻辑1和逻辑2列,如果你想,但我通常不麻烦(我是一个混乱的编码哈哈)。

    希望这有帮助!

    编辑:akrun的grepl解决方案做我正在做的事情更干净(如中所示,它不需要额外的col)。我绝对推荐这种方法!