0

我有一个包含两列的矩阵,第一列有时是 NA,并且想创建第三列作为第一列的值,除非它是 NA,在这种情况下它采用第二列的值。到目前为止,我有一个 for 循环,但我确信在 R 中有更好的方法来做到这一点。

matrixA$Age3 <- 1:length(matrixA$Age)
for(i in 1:length(matrixA$Age3))
{
  if(!is.na(matrixA$Age[i]))
  {
    matrixA$Age3[i] = matrixA$Age[i]
  }else
  {
    matrixA$Age3[i] = matrixA$Age2[i]
  }
}
4

2 回答 2

2
matrix$Age3 <- ifelse(!is.na(matrix$Age),matrix$Age,matrix$Age2)
于 2013-11-06T17:30:34.430 回答
1

也许,只是为了好玩,

matrix$Age3 <- sapply(1:nrow(matrix), function(j) matrix[j,(2-!is.na(foo[j,1]))])

(如果他有这样的事情,向 CSGillespie 道歉,因为他删除了他的)

编辑:正如 eddi 正确建议的那样,这里是对我的想法的一些扩展和测试。我现在因为我错误地假设“ifelse”是一个时间猪而受到适当和公开的羞辱。switch更容易阅读,但至少对于这个小数据集和有限的开关集,时间差异并不显着。(我可能已经确定了确切的截止值,但这两个函数的有效操作在这里很重要)。

# foo is a 2e4 row by 5 column matrix of runif values 

ifelse4 <- function(foo) ifelse(foo[,1] > 0.8,foo[,2],ifelse(foo[,1] > 0.6,foo[,3],ifelse(foo[,1] > .4 , foo[,4],ifelse(foo[,1] > .2 , foo[,5], foo[,1])))) 

switch4l <- function(foo) {

 for(j in 1:nrow(foo)) {
         switch( ceiling(foo[j,1]*5),
            foo[j,1],
            foo[j,5],
            foo[j,4],
            foo[j,3],
            foo[j,2] )
        }
        }


    microbenchmark(ifelse4(foo),switch4l(foo),times=10)

    Unit: milliseconds
          expr      min       lq   median       uq      max neval
  ifelse4(foo) 31.37346 31.87336 32.21567 32.44509 33.21182    10
 switch4l(foo) 28.03629 28.31339 28.61871 28.99588 29.78014    10
于 2013-11-06T18:24:56.163 回答