使用多个变量中的条件替换R中的变量

时间:2020-08-25 21:29:58

标签: r replace

我进行了一些搜索,但找不到最合适的关键词来表达我的问题,所以我想我会在这里提问。

我正在处理R中的一个数据帧,该数据帧具有两个表示数据点身份的变量。在下面的示例中,A和1代表同一个人,B和2相同,C和3也相同,但是它们被混合在原始数据中。

ID1 ID2 Value
  A   1   0.5
  B   2   0.8
  C   C   0.7
  A   A   0.6
  B   2   0.3
  3   C   0.4
  2   2   0.3
  1   A   0.4
  3   3   0.6

我想要实现的是通过仅使用一个标识符来统一身份,因此可以是:

ID1 ID2 Value ID
  A   1   0.5  A
  B   2   0.8  B
  C   C   0.7  C
  A   A   0.6  A
  B   2   0.3  B
  3   C   0.4  C
  2   2   0.3  B
  1   A   0.4  A
  3   3   0.6  C

或:

ID1 ID2 Value ID
  A   1   0.5  1
  B   2   0.8  2
  C   C   0.7  3
  A   A   0.6  1
  B   2   0.3  2
  3   C   0.4  3
  2   2   0.3  2
  1   A   0.4  1
  3   3   0.6  3

我可能可以通过使用ifelse函数来实现它,但这意味着我必须为每个条件编写两个ifelse语句,而且看起来效率不高,所以我想知道是否有更好的方法可以做吧。这是示例数据集。

df=data.frame(ID1=c("A","B","C","A","B","3","2","1","3"),
              ID2=c("1","2","C","A","2","C","2","A","3"),
              Value=c(0.5,0.8,0.7,0.6,0.3,0.4,0.3,0.4,0.6))

非常感谢您的帮助!

编辑:

为澄清起见,我在真实数据中拥有的两个标识符是更长的文本字符串,而不仅仅是ABC和123。抱歉,我并不清楚。

2 个答案:

答案 0 :(得分:2)

一种选择是检测仅是数字的元素,转换为整数,然后在LETTERS中获得相应的case_when

library(dplyr)
library(stringr)
df %>%
    mutate(ID = case_when(str_detect(ID1, '\\d+')~ 
           LETTERS[as.integer(ID1)], TRUE ~ ID1))
#   ID1 ID2 Value ID
#1   A   1   0.5  A
#2   B   2   0.8  B
#3   C   C   0.7  C
#4   A   A   0.6  A
#5   B   2   0.3  B
#6   3   C   0.4  C
#7   2   2   0.3  B
#8   1   A   0.4  A
#9   3   3   0.6  C

或更紧凑

df %>%
    mutate(ID = coalesce(LETTERS[as.integer(ID1)], ID1))

如果我们有不同的值集,则创建一个键/值数据集并进行联接

keyval <- data.frame(ID1 = c('1', '2', '3'), ID = c('A', 'B', 'C'))
left_join(df, keyval) %>% mutate(ID = coalesce(ID, ID1))

答案 1 :(得分:2)

使用replace

的基本R选项
within(
  df,
  ID <- replace(
    ID1,
    !ID1 %in% LETTERS,
    LETTERS[as.numeric(ID1[!ID1 %in% LETTERS])]
  )
)

ifelse

within(
  df,
  ID <- suppressWarnings(ifelse(ID1 %in% LETTERS,
    ID1,
    LETTERS[as.integer(ID1)]
  ))
)

给出

  ID1 ID2 Value ID
1   A   1   0.5  A
2   B   2   0.8  B
3   C   C   0.7  C
4   A   A   0.6  A
5   B   2   0.3  B
6   3   C   0.4  C
7   2   2   0.3  B
8   1   A   0.4  A
9   3   3   0.6  C