【问题标题】:Ignoring values or NAs in the sample function忽略示例函数中的值或 NA
【发布时间】:2012-04-15 17:46:39
【问题描述】:

我在 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


    【解决方案1】:

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

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

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

    sample_n(df[complete.cases(df), ], n)
    

    【讨论】:

      【解决方案2】:

      我认为@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's或有一个完整的列有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
      

      我想这就是您正在寻找的(至少这可能是另一种方法)。

      【讨论】:

        【解决方案3】:

        可能有更好的方法,但 sample 似乎没有任何与 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)
        

        【讨论】:

        • 是的,我注意到失败了。我从中获取样本并使用它来生成更多复制品,从中获取更多样本。我解决了问题,但您的解决方案比我的要好。
        猜你喜欢
        • 1970-01-01
        • 2018-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-11
        • 1970-01-01
        • 2012-03-19
        相关资源
        最近更新 更多