如何使用dplyr有条件地按组更改列中的值?

时间:2019-04-22 19:55:47

标签: r dplyr

我有这样的数据:

g1 g2 var 
 1  a Yes 
 1  a No 
 1  a No 
 1  b Yes 
 1  b Yes 
 1  b Yes 
 2  a No 
 2  a No 
 2  a No

如果每个g1&g2组中var中至少有一个Yes,我想将var中的所有值更改为Yes。我尝试使用group_by和mutate,replace,ifelse的组合,但均未成功。任何帮助表示赞赏。

4 个答案:

答案 0 :(得分:3)

我们可以使用if/else代替ifelse。按'g1','g2',if'是'分组是%in%'var',然后返回“ Yes”或返回“ var”

library(dplyr)
df1 %>% 
   group_by(g1, g2) %>% 
   mutate(var = if("Yes" %in% var) "Yes" else var)
# A tibble: 9 x 3
# Groups:   g1, g2 [3]
#     g1 g2    var  
#  <int> <chr> <chr>
#1     1 a     Yes  
#2     1 a     Yes  
#3     1 a     Yes  
#4     1 b     Yes  
#5     1 b     Yes  
#6     1 b     Yes  
#7     2 a     No   
#8     2 a     No   
#9     2 a     No   

或与case_when

df1 %>% 
   group_by(g1, g2) %>% 
   mutate(var = case_when("Yes" %in% var ~ "Yes", TRUE ~ var))

数据

df1 <- structure(list(g1 = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), g2 = c("a", 
 "a", "a", "b", "b", "b", "a", "a", "a"), var = c("Yes", "No", 
 "No", "Yes", "Yes", "Yes", "No", "No", "No")), class = "data.frame", 
  row.names = c(NA, -9L))

答案 1 :(得分:2)

您也可以这样做:

df %>%
 group_by(g1, g2) %>%
 mutate(var = ifelse(any(var == "Yes"), "Yes", "No"))

     g1 g2    var  
  <int> <chr> <chr>
1     1 a     Yes  
2     1 a     Yes  
3     1 a     Yes  
4     1 b     Yes  
5     1 b     Yes  
6     1 b     Yes  
7     2 a     No   
8     2 a     No   
9     2 a     No   

在这里,如果“ var”中的任何值(“ g1”和“ g2”中的任何一个)等于Yes,则返回Yes,否则返回No

答案 2 :(得分:1)

以上两种解决方案的另一行代码,但是通过创建新列然后删除并重命名来使用ifelseif_else

library(tidyverse)
df %>% 
  group_by(g1, g2) %>% 
  mutate(var2 = if_else("Yes" %in% var, "Yes", "No")) %>% 
  select(-var, var = var2)

结果:

     g1 g2    var  
  <dbl> <chr> <chr>
1     1 a     Yes  
2     1 a     Yes  
3     1 a     Yes  
4     1 b     Yes  
5     1 b     Yes  
6     1 b     Yes  
7     2 a     No   
8     2 a     No   
9     2 a     No   `

答案 3 :(得分:0)

一种非个案的if_else方式,很有趣

df1 %>% 
group_by(g1,g2) %>% 
arrange (g1,g2,var) %>% 
mutate(var=last(var)) 

 # arranged alphabetically, var values may be changed to the last value by groups -- Yes in this case


         g1 g2    var  
      <int> <chr> <chr>
    1     1 a     Yes  
    2     1 a     Yes  
    3     1 a     Yes  
    4     1 b     Yes  
    5     1 b     Yes  
    6     1 b     Yes  
    7     2 a     No   
    8     2 a     No   
    9     2 a     No