【问题标题】:R: Conditional statement iterating over adjacent columnsR:迭代相邻列的条件语句
【发布时间】:2014-09-19 21:25:56
【问题描述】:

假设我有以下data.frame

>tmp

   user      start.date       X03.16.2013 X03.17.2013 X03.18.2013  X03.19.2013
   Allison   2013-03-15         5           5           0           2
   Andrew    2013-03-15         2           0           0           0
   Carl      2013-03-16         10          8           11          10
   Dora      2013-03-16         5           4           0           0
   Hilary    2013-03-17         NA          3           5           0
   Louis     2013-03-18         NA          NA          8           3
   Mary      2013-03-19         NA          NA          NA          7
   Mickey    2013-03-20         NA          NA          NA          NA

我想为两天或以上零条目的用户指定一个“死亡日”。我的方法是在列上运行一个循环并说“如果tmp[x,j:j+1] 的总和等于零,那么lastdateidtmp[x,j]x”:

for (j in 3:dim(tmp)[2]){
  lastdateid <- apply(tmp, 1, function(x) {
    i <- which(sum(tmp[x,j:j+1])==0); ifelse(length(i), head(i,1), NA)
  })   
} 

上面的循环无限运行,也只是创建了充满NAs 的向量lastdateid。理想情况下,循环将返回 Andrew 的 lastdateidtmp[2,4] 和 Dora 的 tmp[4,5] 并且其他所有人的值为 NA。是什么导致这个循环无限运行?我怎样才能修复这个语句,它给出了预期的结果?请多多包涵,因为我对 R 比较陌生。谢谢!

【问题讨论】:

    标签: r conditional-statements apply


    【解决方案1】:

    这可以替换您的 for 循环。还有几行,但我相信它会更有效率。

    w <- which(t(apply(tmp == 0, 1, cumsum)) == 2, arr.ind = TRUE)
    w[,2] <- w[,2]-1 
    rb <- rbind(w, matrix(, nrow(tmp)-nrow(w), ncol(w)))
    rownames(rb) <- tmp$user[c(x <- w[,2], seq_len(nrow(tmp))[-x])]
    

    结果是什么

    > rb
    #         row col
    # Andrew    2   4
    # Dora      4   5
    # Allison  NA  NA
    # Carl     NA  NA
    # Hilary   NA  NA
    # Louis    NA  NA
    # Mary     NA  NA
    # Mickey   NA  NA
    

    【讨论】:

    • @Richard Scriven 谢谢你的解决方案。由于我对使用 which()apply 替换 for 循环还很陌生,我想知道您是否可以帮助我分解您的第一行。我知道apply(tmp==0,1,cumsum) 是说在 tmp 行上应用函数cumsum(由 MARGIN=1 表示)但我不确定which() 如何知道在两个相邻列上运行 cumsum(将来我希望能够选择多少相邻的单元格相加)。
    • @JMeo 当然。 tmp == 0 将原始数据转换为逻辑矩阵。 t(apply(tmp == 0, 1, cumsum) 在行中运行 cumsum== 2 用于查找第二次出现零的位置。用which(..., arr.ind = TRUE) 包裹它告诉我们第二次出现零的矩阵行和列索引。
    • @Richard Scriven 感谢您抽出宝贵的时间为我完成这一切。我仍在学习如何最有效地使用apply()which() 来代替循环。很有帮助!
    猜你喜欢
    • 1970-01-01
    • 2023-03-26
    • 2014-02-05
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 2021-10-13
    • 2020-06-12
    • 2015-09-12
    相关资源
    最近更新 更多