基于r中的两个条件进行重新编码

时间:2019-10-08 20:09:04

标签: r recode

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

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"时,我想将逻辑值分配为“ FALSE”。

这是我所做的:

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

有什么想法吗? 谢谢

2 个答案:

答案 0 :(得分:2)

我们可以通过在末尾检测子字符串'theta'而不以'X'([^X])作为开始(^)字符来创建'logic'

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

答案 1 :(得分:0)

这不是世界上最干净的(因为它增加了2个不必要的列),但是它可以完成工作:

  transaction_id  location_id  customer_id  revenue
0    AJGDO-12304      2131234         1234      140
1    ODSKF-99130       213124         1345      200

我认为您也可以根据需要删除逻辑1和逻辑2列,但是我通常不会打扰(我是一个凌乱的编码器哈哈)。

希望这对您有帮助!

编辑:akrun的grepl解决方案更干净地完成了我正在做的事情(例如,它不需要额外的列)。我绝对推荐这种方法!