代码之家  ›  专栏  ›  技术社区  ›  T Richard

根据条件交换分组数据中的字符串或值

  •  1
  • T Richard  · 技术社区  · 4 月前

    以下数据帧按id变量分组。对于变量X、Y和Z上的每个id,我希望在第一行将“no”替换为“yes”,前提是且仅当特定id在第一行以外的行中有“yes”。

    id <- c(1,1,1,2,2,3,3)
    X <- c("yes", "no", "no", "no", "no", "no", "no")
    Y <- c("no", "no", "yes", "no", "yes", "no", "no")
    Z <- c("no", "yes", "no", "no", "no", "no", "no")
    df <- data.frame(id, X, Y, Z)
    

    预期为:

    id   X   Y   Z
     1 yes yes yes
     1  no  no  no
     1  no  no  no
     2  no yes  no
     2  no  no  no
     3  no  no  no
     3  no  no  no
    

    我尝试使用ifelse函数,但由于分组而遇到了困难。我想在这里请求帮助。非常感谢。

    2 回复  |  直到 4 月前
        1
  •  4
  •   TarJae    4 月前

    这是一个 dplyr 使用a的解决方案 case_when :

    我们检查共享相同行的每组行 id :

    如果该组中的任何行具有 yes ,则组的第一行更改为 . 对于组的所有后续行,任何 翻转为 no . 所有其他值保持不变。

    library(dplyr)
    
    df %>%
      mutate(
        across(X:Z, ~ case_when(
          row_number() == 1 & any(. == "yes") ~ "yes",
          row_number() > 1 & . == "yes" ~ "no",
          .default = .)), .by = id)
    
     id   X   Y   Z
    1  1 yes yes yes
    2  1  no  no  no
    3  1  no  no  no
    4  2  no yes  no
    5  2  no  no  no
    6  3  no  no  no
    7  3  no  no  no
    
        2
  •  0
  •   mikeblazanin    4 月前

    以下是一种方法:

    library(dplyr)
    
    id <- c(1,1,1,2,2,3,3)
    X <- c("yes", "no", "no", "no", "no", "no", "no")
    Y <- c("no", "no", "yes", "no", "yes", "no", "no")
    Z <- c("no", "yes", "no", "no", "no", "no", "no")
    df <- data.frame(id, X, Y, Z)
    
    df <- mutate(group_by(df, id),
                 rownum = 1:n(),
                 X = ifelse(rownum == 1 & length(X) > 1 & any(X[2:length(X)] == "yes"), 
                               "yes", X),
                 Y = ifelse(rownum == 1 & length(Y) > 1 & any(Y[2:length(Y)] == "yes"),
                               "yes", Y),
                 Z = ifelse(rownum == 1 & length(Z) > 1 & any(Z[2:length(Z)] == "yes"),
                               "yes", Z))