dplyr: case_when 涉及多起案件

dplyr: case_when involving many cases

我有两个数据框:

set.seed(002)
data1 <- data.frame(cbind(
  a1 = sample(letters, 8, replace = TRUE),
  a2 = rpois(8, 10)
), stringsAsFactors = FALSE)

data2 <- data.frame(cbind(
  b1 = paste("area", 1:6, sep = " "),
  b2 = c("e", "s", "o", "y", "d", "v")
), stringsAsFactors = FALSE)

data1
  a1 a2
1  e  9
2  s 10
3  o 12
4  e  9
5  y 16
6  y  9
7  d 11
8  v 13

data2
      b1 b2
1 area 1  e
2 area 2  s
3 area 3  o
4 area 4  y
5 area 5  d
6 area 6  v

我想在 data1 中创建一个名为 a3 的新列,同时将 a1 与 data2 中的信息进行匹配,例如,如果 a1 = "e",则 a3 = "area 1",如果 a1 = "d",则a3 = "area 5" 等等。新的 data1 应该是这样的:

  a1 a2     a3
1  e  9 area 1
2  s 10 area 2
3  o 12 area 3
4  e  9 area 1
5  y 16 area 4
6  y  9 area 4
7  d 11 area 5
8  v 13 area 6  

我可以这样做

data1 %>%
  mutate(a3 = case_when(
    a1 == "e" ~ "area 1",
    a1 == "s" ~ "area 2",
    a1 == "o" ~ "area 3",
    a1 == "y" ~ "area 4",
    a1 == "d" ~ "area 5",
    TRUE ~ "area 6"
  ))

问题是我有很多案例,我要在许多不同案例的数据帧上重复这个。

我可以通过写

来用基数 r 做到这一点
data1$a3 <- NA
for(i in 1:nrow(data2)){
  for(j in 1:nrow(data1)){
    if(data1[j,1] == data2[i,2]){
      data1[j,3] <- data2[i,1]
    }
  }
} 

但我很喜欢 dplyr。感谢任何有关如何使用 dplyr 实现此目的的帮助。

在这种情况下,您似乎真的只是在进行连接。你可以做到

left_join(data1, data2, by=c("a1"="b2"))
#   a1 a2     b1
# 1  e  9 area 1
# 2  s 10 area 2
# 3  o 12 area 3
# 4  e  9 area 1
# 5  y 16 area 4
# 6  y  9 area 4
# 7  d 11 area 5
# 8  v 13 area 6

如果您想要重命名该列或仅合并 data2 中的一个特定列(当它有更多列时),您可以这样做

left_join(data1, data2 %>% select(a1=b2, a3=b1))

此解决方案不使用 dplyr::case_when(),但它确实使用了另一个 dplyr 函数。而不是使用第二个 table 来编写你的 case_when(),你可以只加入 table 然后使用 dplyr::rename().

重命名变量


library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
set.seed(2)
data1 <- data.frame(cbind(a1 = sample(letters, 8, replace = TRUE), a2 = rpois(8, 
  10)), stringsAsFactors = FALSE)

data2 <- data.frame(cbind(b1 = paste("area", 1:6, sep = " "), b2 = c("e", "s", 
  "o", "y", "d", "v")), stringsAsFactors = FALSE)

data1 %>% left_join(data2, by = c(a1 = "b2")) %>% rename(a3 = b1)
#>   a1 a2     a3
#> 1  e  9 area 1
#> 2  s 10 area 2
#> 3  o 12 area 3
#> 4  e  9 area 1
#> 5  y 16 area 4
#> 6  y  9 area 4
#> 7  d 11 area 5
#> 8  v 13 area 6
data1 <- dplyr::left_join(data1, data2, by = c("a1" = "b2"))

数据1:-

a1 a2     b1
e  9   area 1
s 10   area 2
o 12   area 3
e  9   area 1
y 16   area 4
y  9   area 4
d 11   area 5
v 13   area 6