2013-09-27 3 views
11

Я хотел бы подмножить свои данные на основе множественных условий неравенства, используя пакет data.table. Примеры в справочнике data.table показывают, как это сделать с символьными переменными, но не с числовыми неравенствами. Я также вижу, как это сделать, используя функцию подмножества. Но я действительно хотел бы использовать скорость бинарного поиска data.table. Ниже приведен пример того, что я пытаюсь сделать.R data.table соединение с условиями неравенства

library(data.table) 

data <- data.table(X=seq(-5,5,1), Y=seq(-5,5,1), Z=seq(-5,5,1)) 
data 

setkey(data, X, Y, Z) 

#the data.frame way 
data[X > 0 & Y > 0 & Z > 0] 

#the data.table way (does not work as I expected) 
data[J(>0, >0, >0)] 
+4

Подождите, но ... здесь работает «data.frame way», верно? И на самом деле, это не сработает для data.frame. 'J' для« соединения », который подмножает объект как первый шаг; но «путь data.frame» является обычным способом подмножества по неравенствам. – Frank

+2

О, также, чтобы уточнить, 'J' будет принимать значения X, Y и Z, а не условия на них; а затем объединить/присоединиться к этим значениям. И «данные» должны быть задействованы для этого. – Frank

+9

@Frank +1 Мы должны, вероятно, сделать некоторую оптимизацию 'i', чтобы неравенства использовали ключ под капотом. Я предполагаю, что люди вводят во входную виньетку, чтобы не использовать '==', а затем ожидать, что аналогичная концепция применима к векторному сканированию '>'. Возможно, даже '==' должен использовать ключ под капотом, поскольку он более естественный. –

ответ

0

Решение довольно быстрое и простое с использованием пакета dplyr.

install.packages(dplyr) 
library(dplyr) 

newdata <- filter(data, X > 0 , Y > 0 , Z > 0) 

dplyr является одним из самых простых и быстрых пакетов для управления кадрами данных. Проверьте этот большой учебник здесь: http://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html

Команда RStudio уже alsoe произвела хорошую Шпаргалку, здесь: http://www.rstudio.com/resources/cheatsheets/

+0

Как это происходит быстрее или проще, чем просто данные [X> 0 & Y> 0 & Z> 0] '??? Вы оценили? Или вы находите, что писать 'filter' проще, чем писать' ['? –

+0

Я не имел в виду fastEr или simpleEr, но только то, что dplyr решает эту проблему быстрым и простым способом. Спасибо за головы. –

0

бегает несколько тестов

library(dplyr) 
library(data.table) 
library(microbenchmark) 

dt.data.frame.way <- function(data) data[X > 0 & Y > 0 & Z > 0] 
dplyr.way <- function(df) filter(df, X > 0, Y > 0, Z > 0) 
real.data.frame.way <- function(df) df[df$X > 0 & df$Y > 0 & df$Z > 0,] 

data <- data.table(X=seq(-5,5,1), Y=seq(-5,5,1), Z=seq(-5,5,1)) 
setkey(data, X, Y, Z) 
df <- as.data.frame(data) 

microbenchmark(times = 10, 
       dt.data.frame.way(data), 
       dplyr.way(df), 
       real.data.frame.way(df)) 
# Unit: microseconds 
#      expr  min  lq  mean median  uq  max neval 
# dt.data.frame.way(data) 710.426 754.287 871.8784 824.7565 942.998 1180.458 10 
#   dplyr.way(df) 951.309 1045.246 12303.3462 1142.7440 1246.668 112775.934 10 
# real.data.frame.way(df) 137.239 162.591 181.5254 187.9785 197.373 231.594 10 

Простых пример клонирования данных в 5.5 M строк.

data <- data.table(X=seq(-5,5,1), Y=seq(-5,5,1), Z=seq(-5,5,1)) 
data <- rbindlist(lapply(1:5e5, function(i) data)) # 5500000 rows 
setkey(data, X, Y, Z) 
df <- as.data.frame(data) 

microbenchmark(times = 10, 
       dt.data.frame.way(data), 
       dplyr.way(df), 
       real.data.frame.way(df)) 
# Unit: milliseconds 
#      expr  min  lq  mean median  uq  max neval 
# dt.data.frame.way(data) 656.2978 668.0560 730.9246 696.6560 831.0877 846.0517 10 
#   dplyr.way(df) 632.4096 639.1141 709.4308 678.9436 717.3018 1015.7663 10 
# real.data.frame.way(df) 964.4298 1022.1772 1075.8448 1077.4437 1125.0037 1192.7410 10 

Выполнение этой задачи, кажется, трудно улучшить. Часто это зависит от данных.

Смежные вопросы