【问题标题】:Value replacement based on other column actual and previous values基于其他列实际值和先前值的值替换
【发布时间】:2018-12-01 03:15:49
【问题描述】:

当当前 'obs1' 列是 1 并且之前的 'obs1' 列是 0 每个 ID 时,是否有办法设置 cero 列 'result' 中的值,省略循环?

输入数据

df <- data.frame(ID = c(1,1,1,1,1,1,1,1,1,1, 2, 2),
     obs1 = c(1,1,1,1,1,1,0,0,1,1,1,1),
     obs2 = c(1,1,1,0,0,0,1,1,1,0,0,1),
     result1 = c(0,28,63,84,105,135,150,150,150,59, 0,300),
     result2 = c(0,28,63,63,63,63,63,31,59,59,0,0))

期望的输出:

df <- data.frame(ID = c(1,1,1,1,1,1,1,1,1,1,2,2),
     obs1 = c(1,1,1,1,1,1,0,0,1,1,1,1),
     obs2 = c(1,1,1,0,0,0,1,1,1,0,0,1),
     result1 = c(0,28,63,84,105,135,150,150,0,59,0,300),
     result2 = c(0,28,63,63,63,63,0,31,59,59,0,0))

第 6 行“result2”列和第 9 行“result1”列发生变化

【问题讨论】:

    标签: r performance for-loop replace


    【解决方案1】:

    dplyr 的选项可以是:

    library(dplyr)
    df %>% group_by(ID) %>%
      mutate(result1 = ifelse(obs1==1 & lag(obs1, default = 1) == 0, 0, result1)) %>%
      mutate(result2 = ifelse(obs2==1 & lag(obs2, default = 1) == 0, 0, result2)) %>%
      as.data.frame()
    

    使用mutate_at 可以实现通用解决方案:

    df %>% group_by(ID) %>%
      mutate_at(vars(starts_with("result")), 
               funs(ifelse( get(sub("result","obs",quo_name(quo(.))))==1 &
                      lag(get(sub("result","obs",quo_name(quo(.)))),
                                                 default = 1) ==0  ,0,.)
                                                  )) %>%
      as.data.frame()
    
    #    ID obs1 obs2 result1 result2
    # 1   1    1    1       0       0
    # 2   1    1    1      28      28
    # 3   1    1    1      63      63
    # 4   1    1    0      84      63
    # 5   1    1    0     105      63
    # 6   1    1    0     135      63
    # 7   1    0    1     150       0
    # 8   1    0    1     150      31
    # 9   1    1    1       0      59
    # 10  1    1    0      59      59
    # 11  2    1    0       0       0
    # 12  2    1    1     300       0
    

    【讨论】:

    • 这绝对有效!但是我试图在许多列下运行它,关系如下:obs1 - result1, ob2 - result2, obs3 - resul3, obsn - resultn 有没有办法在不写所有关系的情况下做到这一点?
    • @AM.Garcia 好吧。我也用通用解决方案更新了我的答案。它将使用obs1 表示result1obs2 表示result2 等等。我已经使用mutate_atget。看看吧。
    • 完美运行
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-15
    • 2018-02-19
    • 2020-10-17
    • 2019-10-11
    • 1970-01-01
    • 2021-02-20
    相关资源
    最近更新 更多