使用dplyr case_when根据来自另一列的值更改NA值

时间:2019-03-15 01:26:31

标签: r dplyr mutate

structure(list(a = c(NA, 3, 4, NA, 3, "Council" , "Council", 1), b = c("Council A", 3, 4, 
"Council B", 6, 7, 2, 6), c = c(6, 3, 6, 5, 3, 6, 5, 3), d = c(6, 2, 4, 
5, 3, 7, 2, 6), e = c(1, 2, 4, 5, 6, 7, 6, 3), f = c(2, 3, 4, 
2, 2, 7, 5, 2)), .Names = c("a", "b", "c", "d", "e", "f"), row.names = c(NA, 
8L), class = "data.frame")

我试图基于a中的文本使用dplyr mutuate和case_when转换b中的对象。如果a在字符串中包含Council,我想将b中的值转换为Council。

我使用的代码是DF %>% select(a, b) %>% mutate(a =case_when(grepl("Council", b) ~"Council"))

如果所有值不包含字符串“理事会”,则所有值都变成NA。我查看了其他帖子,并尝试了各种方法,包括ifelse。我想保持相同的数据帧,只是将其中的任何NA值都转换为市议会,但仅限于NA值的情况下。

2 个答案:

答案 0 :(得分:3)

来自?case_when

  

如果没有匹配的情况,则返回NA。

因此,对于b中没有“理事会”一词的情况,它将返回NA

您需要在TRUE中定义case_when参数,并将其分配给a,以便在不满足条件时保持值不变。

library(dplyr)

df %>%  
 mutate(a = case_when(grepl("Council", b) ~"Council",
                        TRUE ~ a))


#        a         b c d e f
#1 Council Council A 6 6 1 2
#2       3         3 3 2 2 3
#3       4         4 6 4 4 4
#4 Council Council B 5 5 5 2
#5       3         6 3 3 6 2
#6 Council         7 6 7 7 7
#7 Council         2 5 2 6 5
#8       1         6 3 6 3 2

在这种情况下,您也可以使用基数R实现结果

df$a[grepl("Council", df$b)] <- "Council"

答案 1 :(得分:0)

您还可以使用str_detect软件包中的stringr来实现您的目标。

library(dplyr)
library(stringr)

df <- structure(list(a = c(NA, 3, 4, NA, 3, "Council" , "Council", 1), b = c("Council A", 3, 4, 
                                                                   "Council B", 6, 7, 2, 6), c = c(6, 3, 6, 5, 3, 6, 5, 3), d = c(6, 2, 4, 
                                                                                                                                  5, 3, 7, 2, 6), e = c(1, 2, 4, 5, 6, 7, 6, 3), f = c(2, 3, 4, 
                                                                                                                                                                                       2, 2, 7, 5, 2)), .Names = c("a", "b", "c", "d", "e", "f"), row.names = c(NA, 
                                                                                                                                                                                                                                                                8L), class = "data.frame")

df %>% 
  mutate(a=ifelse(str_detect(b,fixed("council",ignore_case = T)) & is.na(a),"Council",a))