Удаление нулевых строк из фрейма данных дает фрейм данных нулевых строк - PullRequest
1 голос
/ 27 мая 2011

У меня есть скрипт, который имеет несколько контрольных сумм контроля качества, и он попал в набор данных, который не должен был удалять какие-либо выборки (строки) из-за контроля качества.Тем не менее, этот сценарий дал мне неожиданный результат с кадром данных с нулевыми строками.С примерами данных, почему это работает:

data(iris)
##get rid of those pesky factors
iris$Species <- NULL
med <- which(iris[, 1] < 4.9)
medtemp <- iris[-med, ]
dim(medtemp)
[1] 134   4

, но возвращает нулевой ряд данных:

small <- which(iris[, 1] < 4.0)
smalltemp <- iris[-small, ]
dim(smalltemp)
[1] 0 4

Как это происходит:

x <- 0
zerotemp <- iris[-x, ]
dim(zerotemp)
[1] 0 4

Этокажется, что smalltemp фрейм данных должен быть того же размера, что и iris, так как нет строк для удаления вообще.Почему это?

Ответы [ 4 ]

3 голосов
/ 27 мая 2011

Дословно скопировано из Патрика Бернса R Inferno p.41 (Я надеюсь, что это «добросовестное использование» - если кто-то возражает, я его удалю)

отрицательное ничто - это что-то

> x2 <- 1:4
> x2[-which(x2 == 3)]
[1] 1 2 4

Команда, приведенная выше, возвращаетвсе значения в x2 не равны 3.

> x2[-which(x2 == 5)]
numeric(0)

Надежда состоит в том, что приведенная выше команда возвращает все x2, поскольку ни один элемент не равен 5. Реальность разрушит эту надежду.Вместо этого он возвращает вектор нулевой длины.Между этими двумя утверждениями есть тонкая разница:

x[]
x[numeric(0)]

Тонкая разница во входных данных, но нет тонкости в разнице в выходных данных.Существует как минимум три возможных решения исходной проблемы.

out <- which(x2 == 5)
if(length(out)) x2[-out] else x2

Другое решение заключается в использовании логических индексов:

x2[!(x2 %in% 5)]

Или, в некотором смысле, вы можете работать в обратном направлении:

x2[ setdiff(seq along(x2), which(x2 == 5)) ]
2 голосов
/ 27 мая 2011

Это из-за правил того, что делать с индексом, который равен нулю. Допускаются только строго положительные или строго отрицательные показатели. Поскольку [0] ничего не возвращает, а

R> -0 == 0
[1] TRUE

Следовательно, вы ничего не получите, где ожидаете, что упадет ничего.

Проблема identical(0) обрабатывается как индексирование NULL, и это задокументировано для работы, как если бы индексирование осуществлялось 0 и, следовательно, таким же поведением.

Это обсуждается в руководстве по определению языка R

2 голосов
/ 27 мая 2011

Может ли быть так, что во втором примере small оценивается как 0?

Взятие нулевого элемента вектора всегда возвращает пустой вектор:

> foo <- 1:3
> foo
[1] 1 2 3
> foo[0]
integer(0)
> 
2 голосов
/ 27 мая 2011

Вместо того, чтобы использовать which для получения ваших индексов, я бы использовал логический вектор и отрицал его. Таким образом, вы можете сделать это:

small <- iris[, 1] < 4.0
smalltemp <- iris[!small, ]
dim(smalltemp)
[1] 150   4

РЕДАКТИРОВАТЬ: я не думаю, что отрицательный индекс 0 (как в вашем случае) допускается, так как нет 0-го индекса и, следовательно, R не может исключить этот индекс из вашего выбора. Отрицательное индексирование можно интерпретировать как: «верните мне все строки, кроме тех, которые имеют эти индексы».

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