2012-04-02 69 views
4

我在R中有一个矩阵,我想从每行中抽取一个随机样本。我的一些数据是在NA中,但是当采用随机样本时,我不希望NA成为采样的选项。我怎么做到这一点?忽略样本函数中的值或NA

例如,

a <- matrix (c(rep(5, 10), rep(10, 10), rep(NA, 5)), ncol=5, nrow=5) 
a 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 5 5 10 10 NA 
[2,] 5 5 10 10 NA 
[3,] 5 5 10 10 NA 
[4,] 5 5 10 10 NA 
[5,] 5 5 10 10 NA 

当我申请的样本函数这个矩阵输出另一个矩阵我得到

b <- matrix(apply(a, 1, sample, size=1), ncol=1) 
b 

    [,1] 
[1,] NA 
[2,] NA 
[3,] 10 
[4,] 10 
[5,] 5 

相反,我不想NA是能够被输出并希望输出是这样的:

b 
    [,1] 
[1,] 10 
[2,] 10 
[3,] 10 
[4,] 5 
[5,] 10 

回答

8

可能有更好的办法,但样本不会出现r有任何与NAs相关的参数,所以我只是写了一个匿名函数来处理NAs。

apply(a, 1, function(x){sample(x[!is.na(x)], size = 1)}) 

本质上是做你想做的。如果你真的想要的矩阵输出,你可以做

b <- matrix(apply(a, 1, function(x){sample(x[!is.na(x)], size = 1)}), ncol = 1) 

编辑:您没有要求这一点,但我所提出的解决方案并在某些情况下会失败(主要是如果列只包含港定居

a <- matrix (c(rep(5, 10), rep(10, 10), rep(NA, 5)), ncol=5, nrow=5) 
# My solution works fine with your example data 
apply(a, 1, function(x){sample(x[!is.na(x)], size = 1)}) 

# What happens if a row contains only NAs 
a[1,] <- NA 

# Now it doesn't work 
apply(a, 1, function(x){sample(x[!is.na(x)], size = 1)}) 

# We can rewrite the function to deal with that case 
mysample <- function(x, ...){ 
    if(all(is.na(x))){ 
     return(NA) 
    } 
    return(sample(x[!is.na(x)], ...)) 
} 

# Using the new function things work. 
apply(a, 1, mysample, size = 1) 
+0

是的,我注意到失败。我从中抽取样本并使用它来生成更多的重复样本,从中获取更多样本。我做了一个工作,但你的解决方案比我的更好。 – Kevin 2012-04-02 20:32:23

3

我觉得@达诚公司的解决方案工作得很好,但你也可以试试这个:

a <- matrix (c(rep(5, 10), rep(10, 10), rep(NA, 5)), ncol=5, nrow=5) 
matrix(sample(na.omit(as.numeric(a)),ncol(a))) 
    [,1] 
[1,] 10 
[2,] 5 
[3,] 10 
[4,] 10 
[5,] 5 

即使有一个完整的一行NA” S或与NA是一个完整的列,该解决方案可以处理很好,例如:

set.seed(007) 
a <- matrix(sample(1:100, 25), 5) 
a[1,] <- NA 
a[5,1] <- NA 
a[,3] <- NA 
a[5,5] <- NA 
a[3,2] <- NA 

matrix(sample(na.omit(as.numeric(a)),ncol(a))) 
    [,1] 
[1,] 40 
[2,] 1 
[3,] 42 
[4,] 26 
[5,] 32 

我猜这就是你要找的人(至少这可能是另一种方法)。