如何相对于另一列重估某列的某行?

时间:2019-09-17 22:27:12

标签: r matrix

我在矩阵中有2列

            a1      a2
            1        3
            NA       3
            8        4
            NA       2
            NA       1

我想将a1的值放在不为NA的任何地方。

输出:

            a1      a2
            1        1
            NA       3
            8        8
            NA       2
            NA       1

2 个答案:

答案 0 :(得分:1)

最快(我认为最简单)的方法是使用简单子集。但是,我还将在base r和data.table中提供一种ifelse的实现方式(可以提高内存效率)。

library(microbenchmark)
library(data.table)

subset_method <- function(mat) {
  mat[!is.na(mat[,'a1']), 'a2'] <- mat[!is.na(mat[,'a1']), 'a1']
  return(mat)
}

ifelse_method <- function(mat) {
  mat[,'a2'] <- ifelse(is.na(mat[,'a1']), mat[,'a2'], mat[,'a1'])
  return(mat)
}

dt_sub_method <- function(dt) {
  d <- copy(dt)
  d[!is.na(a1), a2 := a1][]
}

dt_ie_method <- function(dt) {
  d <- copy(dt)
  d[, a2 := ifelse(is.na(a1), a2, a1)][]
}


set.seed(1234)
n = 1e4
mat <- matrix(rpois(2*n, 3), ncol = 2)
colnames(mat) <- c('a1', 'a2')
inds <- sample(1:n, floor(.25*n))
mat[inds, 1] <- NA
dt <- data.table(mat)

head(mat, 10)
#>       a1 a2
#>  [1,]  1  2
#>  [2,]  3  3
#>  [3,]  3  3
#>  [4,]  3  6
#>  [5,]  5  1
#>  [6,]  3  2
#>  [7,]  0  2
#>  [8,]  2  1
#>  [9,]  4  2
#> [10,]  3  3
ret <- subset_method(mat)
head(ret, 10)
#>       a1 a2
#>  [1,]  1  1
#>  [2,]  3  3
#>  [3,]  3  3
#>  [4,]  3  3
#>  [5,]  5  5
#>  [6,]  3  3
#>  [7,]  0  0
#>  [8,]  2  2
#>  [9,]  4  4
#> [10,]  3  3
times <- microbenchmark(subset_method(mat), ifelse_method(mat), 
               dt_sub_method(dt), dt_ie_method(dt))
times
#> Unit: microseconds
#>                expr     min       lq     mean   median       uq      max
#>  subset_method(mat) 157.401 169.1010 249.3690 174.9015 279.3505 3402.801
#>  ifelse_method(mat) 237.500 247.2510 361.2280 260.7010 446.9510 3219.001
#>   dt_sub_method(dt) 656.601 785.0015 927.3231 840.8010 901.7510 6646.801
#>    dt_ie_method(dt) 493.701 546.2515 698.5841 577.6515 725.6015 3532.701
#>  neval
#>    100
#>    100
#>    100
#>    100

reprex package(v0.3.0)于2019-09-17创建

答案 1 :(得分:0)

a=c(NA,1,3,5,NA,4,NA)
b=sample(1:100,7,FALSE)
b
for (i in 1:length(a)) {
if (is.na(a[i]))  {} else {b[i]=a[i]} 
}
b