Ответ 1
Что работает для data.frame
работает для data.table
s.
subset(DT, year %in% 1999:2001)
Я пытаюсь подмножить data.table(из пакета data.table) в R (а не в data.frame). У меня есть 4-значный год в качестве ключа. Я хотел бы подмножество, взяв серию лет. Например, я хочу вытащить все записи, которые относятся к 1999, 2000, 2001 годам.
Я попытался передать в моем синтаксисе двоичного поиска DT[J(year)]
следующее:
1999,2000,2001
c(1999,2000,2001)
1999, 2000, 2001
но ни один из них, похоже, не работает. Кто-нибудь знает, как сделать подмножество, где годы, которые вы хотите выбрать, - это не только 1, но и несколько лет?
Что работает для data.frame
работает для data.table
s.
subset(DT, year %in% 1999:2001)
Вопрос не ясен и не дает достаточных данных для работы с НО, но это полезно, поэтому, если кто-то может редактировать его с данными, которые я предоставляю в дальнейшем, можно приветствовать. Название должности также может быть завершено: Мэтью Доулл часто отвечает на вопрос подмножества над двумя векторами, но реже - подмножество-в-в-заявлении на одном-векторе. Я искал какое-то время для ответа, пока не найду его для векторных векторов здесь.
Рассмотрим эти данные:
library(data.table)
n <- 100
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
Запрос типа таблицы данных, соответствующий X[X$a %in% c(10,20),]
, вызывает удивление:
setkey(X,a)
X[.(c(10,20))]
X[.(10,20)] # works for characters but not for integers
# instead, treats 10 as the filter
# and 20 as a new variable
# for comparison :
X[X$a %in% c(10,20),]
Теперь, что лучше? Если ваш ключ уже установлен, data.table, очевидно. В противном случае это может быть не так, как доказывают следующие измерения времени (на моем компьютере с 1,7 ГБ оперативной памяти):
n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
system.time(X[X$a %in% c(10,20),])
# utilisateur système écoulé (yes, I'm French)
# 1.92 0.06 1.99
system.time(setkey(X,a))
# utilisateur système écoulé
# 34.91 0.05 35.23
system.time(X[J(c(10,20))])
# utilisateur système écoulé
# 0.15 0.08 0.23
Но, возможно, у Мэтью есть лучшие решения...
[Мэтью] Вы обнаружили, что тип сортировки numeric
(a.k.a. double
) намного медленнее, чем integer
. На протяжении многих лет мы не разрешали double
в ключах из-за боязни, чтобы пользователи попали в эту ловушку и сообщили об ужасных таймингах, подобных этому. Мы допустили double
в ключах с некоторым трепетом, потому что быстрая сортировка еще не реализована для double
. Быстрая сортировка по integer
и character
довольно хороша, потому что это делается с использованием сортировки. Надеюсь, мы сможем быстро отсортировать (теперь реализовано - см. ниже).numeric
один день!
n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
system.time(setkey(X,a))
# user system elapsed
# 13.898 0.138 14.216
X <- data.table(a=sample(as.integer(c(10,20,25,30,40)),n,replace=TRUE),b=1:n)
system.time(setkey(X,a))
# user system elapsed
# 0.381 0.019 0.408
Помните, что 2
является типом numeric
в R по умолчанию. 2L
- integer
. Хотя data.table
принимает numeric
, он все еще предпочитает integer
.
Быстрая сортировка счисления для чисел выполняется с версии v1.9.0.
n <- 1e7
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)
system.time(setkey(X,a))
# user system elapsed
# 0.832 0.026 0.871
Как и выше, но больше data.table esque:
DT[year %in% c(1999, 2000, 2001)]
Это будет работать:
sample_DT = data.table(year = rep(1990:2010, length.out = 1000),
random_number = rnorm(1000), key = "year")
year_subset = sample_DT[J(c(1990, 1995, 1997))]
Аналогично, вы можете закрепить уже существующую таблицу данных с помощью setkey (existing_DT, year), а затем использовать синтаксис J(), как показано выше.
Я думаю, проблема может заключаться в том, что вы сначала не вводили данные.