2012-04-02 3 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, чтобы иметь какие-либо параметры, связанные с 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) 

Edit: Вы не просили об этом, но предложили мое решение терпит неудачу в некоторых случаях (в основном, если строка содержит только NAs

.
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

3

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

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 

Я думаю, это то, что вы искали (по крайней мере, это может быть другой подход).