Более эффективное объединение совпадающего столбца с дубликатами в data.table
У меня есть два data.table
s, оба из которых разделяют одну переменную; Я пытаюсь добавить переменную, которая отсутствует во второй, но привязана одна к одной к общей переменной.
Это, очевидно, слияние, но поскольку общая переменная имеет несколько экземпляров, мне нужно использовать то, что кажется обходным путем для слияния новой переменной.
Позвольте получить конкретный.
x <- data.table(let = rep(letters[1:3], 2:4),
num = rep(1:3, 2:4), other = rnorm(9))
y <- data.table(let = rep(c("a", "c"), c(10, 6)))
x:
let num other
1: a 1 -0.41695882
2: a 1 -0.59875888
3: b 2 -0.19433915
4: b 2 0.58406046
5: b 2 -0.33922321
6: c 3 -0.63076561
7: c 3 1.06987710
8: c 3 0.08869372
9: c 3 -1.31196123
y:
let
1: a
2: a
3: a
4: a
5: a
6: a
7: a
8: a
9: a
10: a
11: c
12: c
13: c
14: c
15: c
16: c
Я просто хочу добавить столбец num
в y
; поскольку num
соответствует 1-1 с let
, на самом деле не имеет значения, что дублируется.
Здесь работает подход; Я просто почувствовал, что там что-то проще.
setkey(x, let)
setkey(y, let)
y <- x[!duplicated(let), c("let", "num"), with = FALSE][y]
Ответы
Ответ 1
Единственные улучшения, о которых я мог думать, это то, что
-
Вы можете пропустить setkey(x, let)
часть
-
Вы также можете обновить y
по ссылке (вместо создания копии с помощью <-
, а затем вернуть обратно к y
)
Если вы используете текущую стабильную версию версии data.table
(v <= 1.9.4), вам нужно будет использовать allow.cartesian = TRUE
setkey(y,let)
y[x[!duplicated(let)], num := i.num, allow.cartesian = TRUE][]
В качестве альтернативы вы можете использовать unique
вместо duplicated
(оба они имеют методы data.table
)
y[unique(x, by = "let"), num := i.num, allow.cartesian = TRUE]
Здесь другая возможность с использованием нового метода .EACHI
, хотя здесь нет необходимости использовать by=.EACHI
. Я показал вам просто, чтобы выставить эту функцию для вас. Посмотрите этот пост для подробного объяснения того, что это делает и когда это полезно.
y[x, num := unique(i.num), by = .EACHI, allow.cartesian = TRUE]
Изменить: (Спасибо @Arun за это указание)
Нам не нужен аргумент allow.cartesian
здесь, так как в i
дубликатов нет. Фактически, это ошибка, # 742, которая была исправлена в текущая версия разработки (1.9.5). Поэтому вам просто нужно сделать:
y[x[!duplicated(let)], num := i.num]
# or
y[unique(x, by = "let"), num := i.num]
# or (though not recommended in this specific case)
y[x, num := unique(i.num), by = .EACHI]
Ответ 2
Ну, я бы использовал merge
следующим образом, но я не уверен, что он проще, чем то, что вы уже сделали.
merge(y,unique(x[,c('let','num'), with=FALSE]), all.x=TRUE, by='let')
Ответ 3
Согласитесь с @David, сложно получить намного проще. Но ниже обрезать несколько нажатий клавиш: -)
setkey(x,let)
y<-x[!duplicated(let),.(let,num)][y]