Подмножество в data.table

Я пытаюсь подмножить 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, но и несколько лет?

Ответы

Ответ 1

Что работает для data.frame работает для data.table s.

subset(DT, year %in% 1999:2001)

Ответ 2

Вопрос не ясен и не дает достаточных данных для работы с НО, но это полезно, поэтому, если кто-то может редактировать его с данными, которые я предоставляю в дальнейшем, можно приветствовать. Название должности также может быть завершено: Мэтью Доулл часто отвечает на вопрос подмножества над двумя векторами, но реже - подмножество-в-в-заявлении на одном-векторе. Я искал какое-то время для ответа, пока не найду его для векторных векторов здесь.

Рассмотрим эти данные:

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 один день! (теперь реализовано - см. ниже).

Сроки на data.table до 1.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 
# 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.

От версии 1.0.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 

Ответ 3

Как и выше, но больше data.table esque:

DT[year %in% c(1999, 2000, 2001)]

Ответ 4

Это будет работать:

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(), как показано выше.

Я думаю, проблема может заключаться в том, что вы сначала не вводили данные.