подмножество в data.table - PullRequest
       29

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

17 голосов
/ 30 марта 2011

Я пытаюсь поместить data.table (из пакета data.table ) в R (не в data.frame).У меня есть четырехзначный год в качестве ключа.Я хотел бы подмножество, принимая ряд лет.Например, я хочу получить все записи за 1999, 2000, 2001 годы.

Я попытался передать в моем синтаксисе двоичного поиска DT[J(year)] следующее:

1999,2000,2001
c(1999,2000,2001)
1999, 2000, 2001

, нони один из них, кажется, не работает.Кто-нибудь знает, как сделать подмножество, где годы, которые вы хотите выбрать, не просто 1, а несколько лет?

Ответы [ 4 ]

19 голосов
/ 30 марта 2011

То, что работает для data.frame с, работает для data.table с.

subset(DT, year %in% 1999:2001)
15 голосов
/ 08 марта 2013

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

Давайте рассмотрим эти данные:

library(data.table)
n <- 100
X <- data.table(a=sample(c(10,20,25,30,40),n,replace=TRUE),b=1:n)

data.table-styleзапрос, соответствующий 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,75 Go):

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 (он же double) намного медленнее, чем integer.В течение многих лет мы не разрешали вводить ключи double из-за страха, что пользователи попадут в эту ловушку и сообщат о таких страшных сроках.Мы допустили double в ключах с некоторым трепетом, потому что быстрая сортировка для double еще не реализована.Быстрая сортировка по integer и character довольно хороша, потому что они выполняются с использованием сортировки с подсчетом. Надеюсь, мы доберемся до быстрой сортировки numeric в один прекрасный день! (сейчас реализовано - см. Ниже).

Временные характеристики в data.table pre-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.

С 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 
8 голосов
/ 26 мая 2012

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

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

1 голос
/ 06 мая 2014

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

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))]

Аналогично, вы можете набрать уже существующий data.table с помощью setkey (существующие_DT, год), а затем использовать синтаксис J (), как показановыше.

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

...