#r #join #data.table
#r #Присоединиться #data.table
Вопрос:
Мне нужно итеративно выполнять соединения между двумя таблицами data.tables, где имена столбцов являются переменными, которые я ввожу из функции. Я выполнял объединения, используя функциональность data.tables ‘on’, и сталкиваюсь с проблемами, поскольку имена переменных столбцов, похоже, не распознаются.
Например, скажем, у нас есть две таблицы, Table_1 и Table_2, следующим образом:
require(data.table)
n <- 20
Table_1 <- data.table(A = seq_len(n) 1,
B = seq_len(n) 3,
C = seq_len(n) 5)
m <- 15
Table_2 <- data.table(D = seq_len(m) 7,
E = seq_len(m) 9,
F = seq_len(m) 12)
Я могу легко выполнять объединения, где я определяю столбцы явно. например
Table_2[Table_1,on = .(F = C),sum(D.na.rm = T)]
Однако то, что мне нужно сделать, это выполнить несколько сопоставлений для разных столбцов, таких как этот:
require(purrr)
pmap(.l = CJ(x = c("D","F"),y = c("A","B")),
.f = function(x,y) Table_2[Table_1,on = .(x = y),sum(C,na.rm = T)])
Я получаю следующую ошибку:
Error in colnamesInt(x, names(on), check_dups = FALSE) :
argument specifying columns specify non existing column(s): cols[1]='x'
Я пробовал разные вещи, такие как:
- Заключая x и y с помощью «eval()» или «noquote»
- Размещение функции pmap внутри data.table, а не снаружи, как показано выше.
Ни один из подходов не работает. Любая помощь была бы с благодарностью принята, поскольку, очевидно, будет крайне неэффективно выписывать отдельные операторы объединения!
Спасибо, Фил
Редактировать:
Ниже было предложено рассмотреть возможность использования функции «слияние». Теоретически, это сработало бы для приведенного выше примера, однако я не упоминал выше, что мне действительно нужно использовать неэквивалентные соединения, что означает, что, насколько мне известно, я не могу использовать «слияние». В моем реальном случае будут комбинации равнозначных и неэквивалентных соединений, которым мне нужно сопоставить имена столбцов с помощью функции.
Я предоставил последующий пример с целевым выводом. В примере есть только два оператора объединения, но мне нужно, чтобы решение было достаточно гибким для обработки нескольких:
Я хочу следующее выражение:
pmap(.l = list(x1 = "D",x2 = "A",x3 = "E",x4 = "B"),
.f = function(x1,x2,x3,x4) (Table_2[Table_1,on = .(x1 = x2,
x3 > x4),sum(C,na.rm = T)]))
Чтобы выдать тот же результат, что и этот:
Table_2[Table_1,on = .(D = A,
E > B),sum(C,na.rm = T)]
т.е. 310 в этом примере.
Еще раз спасибо, Фил
Комментарии:
1. Можете ли вы показать ожидаемый результат с учетом входных данных?
2. Вы пробовали функцию слияния ? Параметры by.x и by.y запрашивают строки в качестве имен столбцов, которые также могут быть в переменных.
3. @sindri_baldur — пожалуйста, смотрите мой пересмотренный вопрос выше с целевым выводом. Спасибо
4. @cdalitz — спасибо за это. Это сработало бы в приведенном выше примере, но я не упомянул всю сложность моего реального сценария, где требуются неравные соединения. Пожалуйста, смотрите мой исправленный вопрос с целевым выводом.
Ответ №1:
Я только что выяснил, как это сделать методом проб и ошибок:
pmap(.l = list(x1 = "D",x2 = "A",x3 = "E",x4 = "B"),
.f = function(x1,x2,x3,x4) (Table_2[Table_1,on =
c(paste0(x1,"==",x2),paste0(x3,">",x4)),
sum(C,na.rm = T)]))