Игнорирование значений или NA в функции выборки - PullRequest
5 голосов
/ 02 апреля 2012

У меня есть матрица в 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

Ответы [ 3 ]

8 голосов
/ 02 апреля 2012

Возможно, есть лучший способ, но образец, похоже, не имеет никаких параметров, связанных с 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 голосов
/ 21 апреля 2012

Я думаю, что решение @ 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, это решение может отлично работатьНапример:

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 голосов
/ 01 марта 2019

Пробовал некоторые решения выше, но по какой-то причине я продолжал получать эту ошибку:

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

Этот код (который использует sample_n (от dplyr) и complete.cases) работает как шарм и довольно просто, ИМХО:

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