【问题标题】:Conditional and/or nested ifelse mutate logic with dplyr使用 dplyr 的条件和/或嵌套 ifelse 变异逻辑
【发布时间】:2015-02-09 19:26:53
【问题描述】:

我有一个这样排列的数据集:

ID   A   B  C   D   Win  Loss
001  NA  3  NA  NA  6    NA  
002  NA  NA NA  NA  NA   17
003  1   5  12  18  NA   22
004  NA  7  9   NA  31   NA
005  8   2  NA  NA  NA   14
006  2   6  12  19  25   NA
007  NA  NA NA  NA  6    NA 

在这个数据集中,ID 应该按时间顺序通过每个阶段(A、B、C、D)并在最后达到赢/输(ID 003 和 006)

但是,有时 ID 会向后移动(ID 005),有些会跳过阶段(ID 001 和 004),有些则直接进入赢/输(ID 002 和 007)。

我想用 dplyr 变异逻辑来调用这些。输出:

ID   A   B  C   D   Win  Loss  Backwards Skip  Just W/L
001  NA  3  NA  NA  6    NA    F         T     F
002  NA  NA NA  NA  NA   17    F         T     T
003  1   5  12  18  NA   22    F         F     F
004  NA  7  9   NA  31   NA    F         T     F
005  8   2  NA  NA  NA   14    T         T     F
006  2   6  12  19  25   NA    F         F     F
007  NA  NA NA  NA  6    NA    F         T     T

我知道我应该使用类似于this 的逻辑,但我就是想不通。

提前致谢。

编辑:

如果您还可以告诉我如何计算每个阶段之间经过的时间/天数,即使它跳过了几个阶段,也可以加分。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    这可以使用base R 来完成。选择感兴趣的列df[LETTERS[1:4]],创建一个存在/不存在“NA”的逻辑矩阵(is.na(df[...))。否定它 (!) 使非 NA 元素变为“TRUE”,获取行明智的总和 rowSums 并否定它!,因此具有 0 非 NA 值的行将变为 TRUE,这将只是输赢的情况。对于“向后”,我们可以对行(MARGIN=1)使用循环方法(apply(),检查非NA元素(diff(na.omit(x)))的差异是否有负数(any(....)<0)。如果有,则表明 ID 向后移动。 “Skip”也类似于“JustWL”,我们得到逻辑矩阵 (is.na(..))、逐行求和 (rowSums) 和双重否定 (!!)。如果至少有一个“NA”,则为 TRUE。

    JustWL <- !rowSums(!is.na(df[LETTERS[1:4]]))
    Backwards <- apply(df[LETTERS[1:4]], 1, function(x) any(diff(na.omit(x))<0))
    Skip <- !!rowSums(is.na(df[LETTERS[1:4]]))
    
    df1 <- data.frame(df, JustWL, Backwards, Skip)
    df1
    #   ID  A  B  C  D Win Loss JustWL Backwards  Skip
    # 1  1 NA  3 NA NA   6   NA  FALSE     FALSE  TRUE
    # 2  2 NA NA NA NA  NA   17   TRUE     FALSE  TRUE 
    # 3  3  1  5 12 18  NA   22  FALSE     FALSE FALSE
    # 4  4 NA  7  9 NA  31   NA  FALSE     FALSE  TRUE
    # 5  5  8  2 NA NA  NA   14  FALSE      TRUE  TRUE
    # 6  6  2  6 12 19  25   NA  FALSE     FALSE FALSE
    # 7  7 NA NA NA NA   6   NA   TRUE     FALSE  TRUE
    

    或者在dplyr中使用相同的代码

    library(dplyr)
     df %>% 
        mutate(JustWL=!rowSums(!is.na(.[LETTERS[1:4]])), 
               Skip=!!rowSums(is.na(.[LETTERS[1:4]]))) %>%
               rowwise() %>% 
               do(data.frame(., Backwards= 
                   any(diff(na.omit(unlist(.[LETTERS[1:4]])))<0)))
    

    【讨论】:

    • 你能解释一下backwards any(diff() 函数和skip !! 命令是如何工作的吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-27
    • 2020-10-31
    • 2023-04-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多