Ошибка объединения двух таблиц data.tables

Я пытаюсь использовать таблицу данных в качестве таблицы поиска:

> (dt <- data.table(myid=rep(11:12,3),zz=1:6,key=c("myid","zz")))
   myid zz
1:   11  1
2:   11  3
3:   11  5
4:   12  2
5:   12  4
6:   12  6
> (id2name <- data.table(id=11:14,name=letters[1:4],key="id"))
   id name
1: 11    a
2: 12    b
3: 13    c
4: 14    d

Я хочу

> (res <- data.table(myid=rep(11:12,3),zz=1:6,name=rep(letters[1:2],3),key=c("myid","zz")))
   myid zz name
1:   11  1    a
2:   11  3    a
3:   11  5    a
4:   12  2    b
5:   12  4    b
6:   12  6    b

однако соединение, которое я пробовал, не удалось:

> dt[id2name]
Starting binary search ...done in 0 secs
Error in vecseq(f__, len__, if (allow.cartesian) NULL else as.integer(max(nrow(x),  : 
  Join results in 8 rows; more than 6 = max(nrow(x),nrow(i)). Check for duplicate key values in i, each of which join to the same group in x over and over again. If that's ok, try including `j` and dropping `by` (by-without-by) so that j runs for each group to avoid the large allocation. If you are sure you wish to proceed, rerun with allow.cartesian=TRUE. Otherwise, please search for this error message in the FAQ, Wiki, Stack Overflow and datatable-help for advice.
Calls: [ -> [.data.table -> vecseq

Что я делаю неправильно?

PS. Я согласен на любой альтернативный способ получения результатов; каков самый идиоматический способ сделать то, что я хочу (dt все еще должен быть data.table, но id2name может быть чем угодно, отображающим int на что-то еще, если int не считается векторным индексом).


person sds    schedule 27.03.2014    source источник


Ответы (1)


> dt[id2name, allow.cartesian=T, nomatch=0]
   myid zz name
1:   11  1    a
2:   11  3    a
3:   11  5    a
4:   12  2    b
5:   12  4    b
6:   12  6    b

data.table пытается уберечь вас от самого себя, если у вас произошло непреднамеренное объединение ключей с повторяющимися значениями. Обратите внимание, что сообщение об ошибке (в конце концов) говорит вам, что делать, если вы уверены, что знаете, что делаете.

В качестве альтернативы:

> id2name[dt]
   id name zz
1: 11    a  1
2: 11    a  3
3: 11    a  5
4: 12    b  2
5: 12    b  4
6: 12    b  6
person BrodieG    schedule 27.03.2014
comment
Обратите внимание, что ключ во второй таблице (I=id2name) уникален, поэтому декартово произведение не требуется. - person sds; 28.03.2014
comment
@sds, я думаю, что проверка, которую выполняет data.table, только сравнивает результат соединения с длиной внутренней таблицы, на самом деле она не определяет, является ли это декартовым соединением или нет. Таким образом, имя аргумента не идеально. - person BrodieG; 28.03.2014
comment
спасибо, интересно, можно ли name вставить в dt с помощью :=? - person sds; 28.03.2014
comment
@sds, прочитайте объяснение allow.cartesian в ?data.table. Я думаю, это многое прояснит. Слово декартово используется здесь вольно. - person Arun; 28.03.2014
comment
@sds dt[id2name, name := i.name, allow.cartesian = T] - person eddi; 28.03.2014
comment
@eddi, спасибо за напоминание о i.; продолжайте забывать об этом. - person BrodieG; 28.03.2014
comment
@BrodieG между прочим, в этом случае, поскольку в исходной таблице нет name, она будет работать и без i., так она просто понятнее и более обобщаема. - person eddi; 28.03.2014