R: При использовании data.table как получить столбцы y, когда я делаю x [y]? - PullRequest
14 голосов
/ 22 января 2011

ОБНОВЛЕНИЕ : старый вопрос ... он был решен с помощью data.table v1.5.3 в феврале 2011 года.

Я пытаюсь использовать data.table пакет, и мне действительно нравятся ускорения, которые я получаю, но я озадачен этой ошибкой, когда я x[y, <expr>], где x и y являются "таблицами данных" с тем же ключом, а <expr> содержит столбецимена как x, так и y:

require(data.table)
x <- data.table( foo = 1:5, a = 5:1 )
y <- data.table( foo = 1:5, boo = 10:14)
setkey(x, foo)
setkey(y, foo)
> x[y, foo*boo]
Error in eval(expr, envir, enclos) : object 'boo' not found

ОБНОВЛЕНИЕ ... Чтобы прояснить функции, которые я ищу в приведенном выше примере: мне нужно сделать эквивалент следующего:

with(merge(x,y), foo*boo)

Однако, согласно приведенной ниже выдержке из data.table FAQ, это должно сработать:

Наконец, хотя кажется, что x [y] не возвращает столбцы вy, вы можете использовать столбцы из y в выражении j.Это то, что мы подразумеваем под унаследованной областью соединения.Почему бы просто не вернуть объединение всех столбцов из x и y, а затем запустить выражения для этого?Это сводится к эффективности кода и тому, что быстрее программировать.Когда вы пишете x [y, foo boo], data.table автоматически проверяет выражение j, чтобы увидеть, какие столбцы он использует.Он будет только подмножество или группировать только эти столбцы.Память создается только для столбцов, которые использует j.Допустим, foo в x, а boo в y (вместе с 20 другими столбцами в y).Разве x [y, foo boo] быстрее запрограммировать и запустить быстрее, чем шаг слияния, за которым следует другой шаг подмножества?

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

ОБНОВЛЕНИЕ: Я спросил в списке рассылки справки таблицы данных и авторе пакета (Мэтью Доул) ответил , что действительно приведенный выше FAQ неправильный, поэтому синтаксис, который я используюне будет работать в настоящее время, то есть я не могу ссылаться на столбцы y в аргументе j (т.е. второй), когда я выполняю x[y,...].

1 Ответ

4 голосов
/ 22 января 2011

Я не уверен, хорошо ли я понимаю проблему, и я только начал читать документы библиотеки data.table , но думаю, если вы хотите получить столбцы y , а также сделайте что-нибудь с этими столбцами a , вы можете попробовать что-то вроде:

> x[y,a*y]
     foo boo
[1,]   5  50
[2,]   8  44
[3,]   9  36
[4,]   8  26
[5,]   5  14

Здесь вы получите столбцы y , умноженные на столбец a из x . Если вы хотите получить x s foo , умноженное на y s boo , попробуйте:

> y[,x*boo]
     foo  a
[1,]  10 50
[2,]  22 44
[3,]  36 36
[4,]  52 26
[5,]  70 14

После редактирования: спасибо @Prasad Chalasani за разъяснение вопроса для меня.

Если предпочтительнее простое объединение, то должно работать следующее. Я составил более сложные данные, чтобы увидеть действия глубже:

x <- data.table( foo = 1:5, a=20:24, zoo = 5:1 )
y <- data.table( foo = 1:5, b=30:34, boo = 10:14)
setkey(x, foo)
setkey(y, foo)

Таким образом, в каждый data.table добавлен только дополнительный столбец. Давайте посмотрим merge и сделаем это с data.tables:

> system.time(merge(x,y))
   user  system elapsed 
  0.027   0.000   0.023 
> system.time(x[,list(y,x)])
   user  system elapsed 
  0.003   0.000   0.006 

Из которого последний выглядит намного быстрее. Результаты не идентичны, но могут использоваться таким же образом (с дополнительным столбцом последнего запуска):

> merge(x,y)
     foo  a zoo  b boo
[1,]   1 20   5 30  10
[2,]   2 21   4 31  11
[3,]   3 22   3 32  12
[4,]   4 23   2 33  13
[5,]   5 24   1 34  14
> x[,list(x,y)]
     foo  a zoo foo.1  b boo
[1,]   1 20   5     1 30  10
[2,]   2 21   4     2 31  11
[3,]   3 22   3     3 32  12
[4,]   4 23   2     4 33  13
[5,]   5 24   1     5 34  14

Таким образом, чтобы получить xy, мы могли бы использовать: xy <- x[,list(x,y)]. Чтобы вычислить таблицу данных из одного столбца из xy$foo * xy$boo, может работать следующее:

> xy[,foo*boo]
[1] 10 22 36 52 70

Ну, результат - не таблица данных, а вектор.


Обновление (29.03.2012): спасибо за @David за то, что обратили мое внимание на тот факт, что merge.data.table были использованы в приведенных выше примерах.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...