Создать подгруппы в data.table - PullRequest
1 голос
/ 28 июня 2019

Скажем, у меня есть следующий упрощенный набор данных:

dt <- data.table(id = 1:5, val = c(1, 2, 3, 2, 4))
dt2 <- data.table(id = c(2, 4), val = c(2, 3)) 

Я хочу заменить все значения в dt, которые имеют значение 2. Значение замены указано в dt2.Две таблицы могут быть объединены через идентификатор.Конечное значение должно оставаться неизменным, если значение не равно 2. И если оно равно 2, оно должно стать paste0(dt$val, ".", dt2$val).

Желаемый результат:

row id val
1:  1   1
2:  2   2.2
3:  3   3
4:  4   2.3
5:  5   4

Что я пробовал (работает, но не выглядит элегантно):

merged <- merge(x = dt, y = dt2, by= "id", all.x = TRUE)
merged[!is.na(merged$val.y), ]$val.x <- paste0(
  merged[!is.na(merged$val.y), ]$val.x, ".",
  merged[!is.na(merged$val.y), ]$val.y)
merged[, val.y := NULL]
setnames(x = merged, old = "val.x", new = "val")
merged

Вопрос: Как я могу сделать преобразование более элегантно?

Ответы [ 2 ]

3 голосов
/ 28 июня 2019

R вы ищете обновление присоединиться

dt[dt2, on=.(id), val := paste0(x.val, ".", i.val)]

выход:

   id val
1:  1   1
2:  2 2.2
3:  3   3
4:  4 2.3
5:  5   4

данные:

#val column needs to be of character type to suppress the warning
dt <- data.table(id = 1:5, val = as.character(c(1, 2, 3, 2, 4)))
dt2 <- data.table(id = c(2, 4), val = c(2, 3)) 
2 голосов
/ 28 июня 2019
library(data.table)

# example data
dt <- data.table(id = 1:5, val = c(1, 2, 3, 2, 4))
dt2 <- data.table(id = c(2, 4), val = c(2, 3)) 

Если ваши наборы данных правильно упорядочены, вы можете использовать базу R следующим образом:

dt$val[dt$id %in% dt2$id] = paste0(dt$val[dt$id %in% dt2$id], ".", dt2$val)

dt

#    id val
# 1:  1   1
# 2:  2 2.2
# 3:  3   3
# 4:  4 2.3
# 5:  5   4

В противном случае вы можете использовать это:

dt_merged = merge(dt, dt2, by="id", all.x=T)[, val:=ifelse(is.na(val.y), 
                                                           val.x, 
                                                           paste0(val.x, ".", val.y))]
dt_merged = dt_merged[, c("id","val")]
dt_merged

#    id val
# 1:  1   1
# 2:  2 2.2
# 3:  3   3
# 4:  4 2.3
# 5:  5   4
...