如何在R中使用一个case_when表达式变换两列数据?

5

根据一列中的文本,我想要给另外两列分别赋值一个字符和一个整数。多个case_when条件(左侧)用于给一个列赋字符值,给另一个列赋整数值,但结果(右侧)不同。我使用exprs!!!是因为我只想在一个表中维护表达式列表的基础。

我的代码如下:

library(rlang)
library(tidyverse)

df <- data.frame(a=c("text-1" , "text_2", "text3"))

e1 <- 
  exprs(
    grepl("text-", a) ~ "a",
    grepl("text_", a) ~ "b",
    grepl("text[0-9]", a) ~ "c"
  )

e2 <- 
  exprs(
    grepl("text-", a) ~ 0,
    grepl("text_", a) ~ 1,
    grepl("text[0-9]", a) ~ 2
  )

test <- df %>% mutate(b=case_when(!!!e1),
                      c=case_when(!!!e2)
)

预期结果是:
> test
       a b c
1 text-1 a 0
2 text_2 b 1
3  text3 c 2

但如果有数百万条记录,使用两个具有相同LHS的case_when表达式列表似乎是冗余和低效的。 有什么方法可以更有效地达到相同的结果?


1
c列例如0、1、2(已编辑),或者其他任意值,谢谢zx8754。 - Nils
1
left_join是当仅存在==条件时的一种选择,但涉及到正则表达式时,我会再进行编辑,谢谢Cole。 - Nils
你想只用一个 case_when 吗?但是如果你的 LHS 完全相同,那么如何评估不同的 RHS 呢? - Ronak Shah
我会编写一个返回二列数据框的函数,然后使用cbind合并。 - zx8754
嗨Ronak,是的,那确实是我的问题。 - Nils
在这种特定情况下,您可以使用letters[c(0, 1, 2) + 1]c(0, 1, 2)映射到c(a, b, c),这可用于替换其中一个case_when表达式。 - Joris C.
1个回答

2
最初的回答并没有明确说明主要动机,但是使用@zx8754的建议,我们可以进行以下操作:
library(dplyr)
library(rlang)

e1 <- exprs(
      grepl("text-", a) ~ "a, 0",
      grepl("text_", a) ~ "b, 1",
      grepl("text[0-9]", a) ~ "c, 2")

df %>% 
  mutate(b=case_when(!!!e1)) %>%
  tidyr::separate(b, into = c("b", "c"), sep = ",", convert = TRUE)

#       a b  c
#1 text-1 a  0
#2 text_2 b  1
#3  text3 c  2

谢谢Ronak,我的动机是不想评估每个条件两次,这似乎效率低下,有很多记录需要评估。因此,我也考虑了一种“分离”的解决方案。没有一种命令解决方案吗? - Nils
separate 的参数中添加 convert=T 将列 c 转换为整数。 - Nils

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接