Как я * исключаю *
У меня есть датафрейм (данные), который включает в себя много дат. Я хочу отбросить все до 1970 года. Я могу создать список индексов до 1970 года:
tmp <- which(data$data < '1970-01-01')
[1] 13446 102876 141199
и я хочу создать новую таблицу, которая выпадает из этих трех строк. Что-то вроде:
data.after.1970 <- data[!tmp, ]
Я знаю, что могу создать вектор всех инцидентов после 1970 года и сопоставить его с:
tmp <- which(data$data > '1970-01-01')
data.after.1970 <- data[tmp, ]
Но мне интересно, какой синтаксис я бы использовал, чтобы исключить элементы.
ОБНОВИТЬ
Я наконец только что сделал это:
tmp <- which(data$data > as.Date('1970-01-01'))
data.after.1970 <- data[tmp, ]
и присмотрелся к нему. which(data$data < as.Date('1970-01-01'))
получает три результата, но nrow(data) - nrow(data.after.1970)
показывает, что я упал на 45 строк. summary(datae$date)
прояснили:
summary(data$date)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
"1933-07-01" "1989-01-25" "1992-07-09" "1992-05-03" "1996-06-10" "2006-09-14" "42"
Поскольку моя цель состояла в том, чтобы получить второй набор данных, чтобы я мог сравнить свои результаты, если я исключу результаты с неправильными датами, я на самом деле хочу также удалить результаты со значениями NA.
Я все еще хочу знать, какой синтаксис я бы использовал, чтобы исключить какой-либо числовой вектор, а не включить его.
3 ответа
Оказывается, это было на самом деле довольно просто.
data.after.1970 <- data[-tmp, ]
создаст новый кадр, data.after.1970
это включает в себя все строки из data
кроме тех, которые соответствуют индексам в tmp
,
which
возвращает числовой вектор для элементов, которые имеют значение ИСТИНА в оценке логического выражения или в самом логическом векторе. Также возможно использовать отрицательную индексацию для удаления элементов. В вашем случае это может выглядеть так:
tmp <- data[ which(data$data < '1970-01-01') , ]
Т.е. возвращаются все строки фрейма данных "data", где столбец "data" меньше "1970-01-01". Вы действительно должны научиться использовать более конкретные имена, чем "данные". Вы не только создадите путаницу, имея одинаковое имя для объекта и элемента с этим объектом, но также существует функция "данные". Итак, как ваша бедная аудитория должна знать, что вы имели в виду, когда писали код, чем 10 месяцев назад.
Для того, чтобы адресовать тех из них, кто не любит использование which
Я бы ответил, что это позволяет избежать проблемы, заключающейся в том, что функция "[" будет возвращать все строки, для которых либо условие TRUE, либо NA. Ты можешь использовать subset
который имеет то же преимущество, но не рекомендуется для использования в программировании, только для интерактивного использования. Вы можете сделать это так, как это делает подмножество, и добавить предложение, исключающее значения NA:
tmp <- data[ data$data < '1970-01-01 & !is.na(data$data) , ]
... и я бы сказал, что версия использует which
"чище", чем эта альтернатива. Есть обратная сторона which
что возникает в случае, когда никакие значения не являются ИСТИНАМИ, и вы используете отрицательную индексацию, в этом случае, вопреки ожиданию, используя dfrm[-which(condition) , ]
не даст вам то, что вы хотите, а пустой вектор. Итак, правило таково: используйте which
но не с отрицательной индексацией.
Чтобы объяснить немного больше, если вы запустите:
data$date > '1970-01-01'
вы увидите, что он возвращает логический вектор TRUE/FALSE
который вы можете использовать, чтобы выбрать необходимые строки. Это работает как в этом примере:
test <- 1:3
test[c(TRUE,FALSE,TRUE)]
# result
[1] 1 3
Как отмечает @DWin в своем ответе, при наличии NA
значения, которые также будут возвращены, а также TRUE
ценности. Как в:
test <- c(NA,1:3)
test > 2
# result
[1] NA FALSE FALSE TRUE
test[test>2]
# result
[1] NA 3
which
оператор возвращает все TRUE
только индексы, что позволяет избежать проблемы с NA
ценности.
test <- c(NA,1:3)
which(test>2)
# result - the fourth value of test is > 2
[1] 4
> test[4]
# result - return the fourth value of test
[1] 3
test[which(test>2)]
# result - return the fourth value of test as the
# which statement has identified it is > 2
[1] 3
Кроме того, я понимаю, что вам, вероятно, на самом деле нужно сделать что-то вроде:
data$date > as.Date('1970-01-01')
... чтобы ваш пример работал правильно. Это при условии, конечно, ваш date
столбец также на самом деле Date
объект, а не просто текст.