忽略示例函数中的值或NA

问题描述 投票:5回答:3

我在R中有一个矩阵,我想从每一行中取一个随机样本。我的一些数据是在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
r matrix sample apply
3个回答
8
投票

可能有更好的方法,但样本似乎没有任何与NA相关的参数,所以我只是写了一个匿名函数来处理NA。

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)

编辑:您没有要求这个,但我提议的解决方案在某些情况下确实失败(主要是如果一行只包含NA。

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)

4
投票

我认为@Dason的解决方案效果很好,但你也可以试试这个:

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的完整行或带有NA'S的完整列,此解决方案也可以完美处理,例如:

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

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


0
投票

试过上面的一些解决方案,但由于某种原因,我一直收到这个错误:

Error in sample.int(length(x), size, replace, prob): 
     invalid first argument

这段代码(使用sample_n(来自dplyr)和complete.cases)就像一个魅力,非常简单,恕我直言:

sample_n(df[complete.cases(df), ], n)
© www.soinside.com 2019 - 2024. All rights reserved.