代码之家  ›  专栏  ›  技术社区  ›  deca

将ifelse()应用于在另一列上有动态意外事件的多个列

  •  1
  • deca  · 技术社区  · 7 年前

    我有一个数据集包含 NAs . 我想用依赖于另一个辅助列的值填充这些值。但是,此辅助列是动态的,并根据主列进行更改。

    举例来说,我想复制以下过程:

    l1 <- c("A", "A", "A", "A")
    l2 <- c(NA, "B", "B", "B")
    l3 <- c(NA, NA, "C", "C")
    l4 <- c(NA, NA, NA, "D")
    
    prodmap <- data.frame(l1, l2, l3, l4)
    
    prodmap[] <- lapply(prodmap, as.character) 
    
    prodmap$l2 <- ifelse(is.na(prodmap$l2), prodmap$l1, prodmap$l2)
    prodmap$l3 <- ifelse(is.na(prodmap$l3), prodmap$l2, prodmap$l3)
    prodmap$l4 <- ifelse(is.na(prodmap$l4), prodmap$l3, prodmap$l4)
    

    我该怎么做?特别是,列应该以它们的名称动态调用,而不需要像我上面所做的那样进行手动规范。我相信循环可能是一种选择,但到目前为止,我还不能弄清楚如何处理动态更改列名的挑战。

    2 回复  |  直到 7 年前
        1
  •  1
  •   akrun    7 年前

    由于下一列取决于前一列,因此我们可以使用 for 使用索引循环以执行此操作

    for(i in 2:ncol(prodmap)) prodmap[[i]] <- ifelse(is.na(prodmap[[i]]), 
                  prodmap[[i-1]], prodmap[[i]])
    prodmap
    #  l1 l2 l3 l4
    #1  A  A  A  A
    #2  A  B  B  B
    #3  A  B  C  C
    #4  A  B  C  D
    

    如果要使用列名而不是列索引,请创建两个 vector s列名称,删除第一个和最后一个列名称(“nm1”,“nm2”),循环遍历 矢量 ,根据索引提取相应的列名并更新“prodmap”列

    nm1 <- tail(names(prodmap), -1)
    nm2 <- head(names(prodmap), -1)
    for(i in seq_along(nm1)) {
      prodmap[[nm1[i]]] <- ifelse(is.na(prodmap[[nm1[i]]]), 
                                   prodmap[[nm2[i]]],
                                   prodmap[[nm1[i]]])
       }
    

    注意:假设NAS可以分布在列中的任何位置

        2
  •  1
  •   markus    7 年前

    使用选项 upper.tri

    prodmap[upper.tri(prodmap)] <- t(prodmap)[upper.tri(prodmap)]
    prodmap
    #  l1 l2 l3 l4
    #1  A  A  A  A
    #2  A  B  B  B
    #3  A  B  C  C
    #4  A  B  C  D
    

    其目的是填充所有在 prodmap[upper.tri(prodmap)] 我们第一次换位时得到的值 prodmap 然后从上三角中找到的结果矩阵中提取值。