Как удалить строку, которая содержит только пропущенные значения в R? - PullRequest
5 голосов
/ 25 августа 2011

У меня большой набор данных с 11 столбцами и 100000 строк (например), в котором у меня есть значения 1,2,3,4. Где 4 - пропущенное значение Некоторые из строк полностью отсутствуют. то есть 4 во всех 11 столбцах. Например

"4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"  "4"   "4"

Теперь мне нужно удалить только те строки, которые полностью отсутствуют. Проще говоря, я хочу сохранить строки с отсутствующим значением меньше 11. Я использовал na.omit, но в моем случае это не работает.

Заранее спасибо.

Ответы [ 6 ]

11 голосов
/ 25 августа 2011

Возможно, ваш лучший вариант - использовать идиому R для работы с пропущенными значениями или значениями NA. После того как вы закодировали NA значения, вы можете работать с complete.cases, чтобы легко достичь своей цели.

Создать пример данных с пропущенными значениями (т. Е. Со значением 4):

set.seed(123)
m <- matrix(sample(1:4, 30, prob=c(0.3, 0.3, 0.3, 0.1), replace=TRUE), ncol=6)
m[4, ] <- rep(4, 6)

Заменить все значения, равные 4, на NA:

m[m==4] <- NA
m
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    1   NA    2    2    2
[2,]    2    3    3    1    2    3
[3,]    3    2    2    1    2    3
[4,]   NA   NA   NA   NA   NA   NA
[5,]   NA    3    1   NA    2    1

Теперь вы можете использовать различные функции, которые работают со значениями NA. Например, complete.cases вернет только, как вы уже догадались, завершенные дела:

m[complete.cases(m), ]

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    2    3    3    1    2    3
[2,]    3    2    2    1    2    3

Для получения дополнительной информации см. ?complete.cases или ?na.fail в пакете stats.

3 голосов
/ 28 августа 2012

Я нашел это решение в другом месте и вставляю его здесь, используя код Андри для генерации начального набора данных.

Сначала сгенерируйте набор данных:

set.seed(123)
m <- matrix(sample(1:4, 30, prob=c(0.3, 0.3, 0.3, 0.1), replace=TRUE), ncol=6)
m[4, ] <- rep(4, 6)
m[m==4] <- NA
m

Вот начальный набор данных:

1    1    NA   2    2    2
2    3    3    1    2    3
3    2    2    1    2    3
NA   NA   NA   NA   NA   NA
NA   3    1    NA   2    1

Теперь удалите строки, которые содержат только отсутствующие наблюдения:

m[rowSums(is.na(m))<ncol(m),] 

Вот результат:

1    1    NA   2    2    2
2    3    3    1    2    3
3    2    2    1    2    3
NA   3    1    NA   2    1
2 голосов
/ 03 октября 2012

Использование data.table для повышения эффективности памяти. Решение, создающее is.na(x), создает набор данных размером с исходный и, следовательно, неэффективен.

library(data.table)
DT <- as.data.table(m)
missing_value <- 4
missing <- as.data.table(setNames(as.list(rep(4, length(DT)), names(DT))
setkeyv(DT, names(DT))
setkey(missing, names(DT))

DT[-DT[(missing),which=T]]

и это, и решение @ JoshuaUlrich быстро для больших данных

set.seed(21)
m <- matrix(sample(1:6, 1100000, replace=TRUE), ncol=11)
missVal <- 4
missing_rows <- sample(100000, 53)
m[missing_rows, ] <- rep(missVal, 11)

DT <- as.data.table(m)
setkeyv(DT, names(DT))
missing <- setNames(as.list(rep(missVal, 11)), names(DT))

system.time({DT1 <- DT[-DT[missing,which=T]]})
## user  system elapsed 
## 0.02    0.00    0.01 
system.time({m1 <- m[ rowSums((m==missVal)) != NCOL(m), ]})
## user  system elapsed 
## 0.02    0.02    0.03 
2 голосов
/ 25 августа 2011

Это самое быстрое решение, которое я могу придумать. Я буду использовать пример данных, похожих на @ Andrie.

set.seed(21)
m <- matrix(sample(1:6, 110, replace=TRUE), ncol=11)
missVal <- 4
m[4, ] <- rep(missVal, 11)
m <- m[ rowSums((m==missVal)) != NCOL(m), ]

Последняя строка работает, потому что m==missVal возвращает матрицу логических (TRUE / FALSE) значений. rowSums преобразует TRUE в 1 и FALSE в 0, поэтому в этом случае мы знаем, что все столбцы 4 всякий раз, когда rowSums возвращает 11.

2 голосов
/ 25 августа 2011

Реальным быстрым способом было бы использовать немного математики.Предполагая, что ваш фрейм данных называется datf

rsum <- rowSums(datf)
datf <- datf[rowSums != 44,] #11 * 4

(работает и для матрицы)

1 голос
/ 25 августа 2011

Что-то вроде этого должно сработать (и должно работать как для матриц, так и для data.frames):

ac<-matrix(c("4","4","4","4","4","4","4","3","3","4","4", rep("4", 11)), nrow=2, ncol=11, byrow=TRUE)

rowsToRemove<-which(apply(ac, 1, function(currow){
    all(currow=="4")
}))

Теперь вы можете просто сделать

newac<-ac[-rowsToRemove,]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...