将ifelse()应用于动态列在另一列上的多个列

时间:2019-02-11 17:52:25

标签: r loops

我有一个包含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 个答案:

答案 0 :(得分:1)

使用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中所有的缺失值,然后从上三角中找到的结果矩阵中提取值

答案 1 :(得分:1)

由于下一列取决于上一列,我们可以使用带有索引的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列名,并删除第一个和最后一个列名('nm1','nm2'),依次遍历vector,根据索引提取相应的列名称,并更新“ 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]]])
   }

注意:假设NA可以分布在列中的任何地方