Создайте новый столбец, используя операции по строкам в данных.Таблица R

#r #data.table

#r #data.table

Вопрос:

У меня есть две data.tables в R следующим образом:

DT_A со столбцами sid , date , value1 , value2 , где sid является первичным ключом и date является вторичным ключом.

DT_B содержит столбцы sid , date1 , date2 , date3 , …., date12 . Вот sid первичный ключ , и , следовательно , каждая строка соответствует уникальному sid , а остальные имена столбцов соответствуют вторичным ключам в DT_A .

Я хочу добавить еще один столбец, в DT_A который i-я строка содержит соответствующий элемент из таблицы DT_B[sid_i, date_i]

Ниже приведен пример кода и желаемый результат:

 require(data.table)
DT_A <- data.table(sid = c(1,2,3,4,5,1,3), 
                   date = c("Jan 2012", "Feb 2012", "April 2012", "May 2012", 
                            "Dec 2012", "Feb   2012", "Oct 2012"),
                   value1 = rep("1", 7), 
                   value2 = rep("1", 7))

DT_B <- data.table(sid = as.character(c(1,2,3,4,5)), 
                   "Jan 2012" = rep("1", 5),
                   "Feb 2012" = rep("2", 5),
                   "March 2012" = rep("3", 5),
                   "April 2012" = rep("4", 5),
                   "May 2012" = rep("5", 5),
                   "June 2012" = rep("6", 5),
                   "July 2012" = rep("7", 5),
                   "Aug          2012" = rep("8", 5),
                   "Sept 2012" = rep("9", 5),
                   "Oct 2012" = rep("10", 5),
                   "Nov 2012" = rep("11", 5),
                   "Dec 2012" = rep("12", 5))

#Set Keys
setkey(DT_A, sid, date)
setkey(DT_B, sid)

#Define Function fun1
fun1 <- function(x){ 
    tryCatch(DT_B[x[1], x[2], with=FALSE], error = function(e) NULL)
}

#Desired Output
DT_A$newCol <- sapply(apply(DT_A, 1, fun1),"[[",1)
DT_A
  

Хотя мой текущий метод работает на этом небольшом примере, мой фактический DT_A имеет 20 миллионов строк. Этот метод полностью зависает там. Можем ли мы выполнить эту операцию более эффективным способом, используя data.table or любой другой метод?

Комментарии:

1. Вы не предоставили DT_A

2. Извините за ошибку, я сделал это сейчас

3. Я думаю, что вопрос следует переформулировать. Речь идет не о выполнении операций по строкам, а о изменении формы и слиянии.

Ответ №1:

Расплавьте свой второй data.table :

 library(reshape2)

DT_B.melted = melt(DT_B, id.vars = 'sid', variable.name = 'date')
  

После того, как он будет расплавлен, вы можете установить для обоих один и тот же ключ и выполнить соединение / назначение / еще много чего:

 setkey(DT_B.melted, sid, date)
setkey(DT_A, sid, date)

DT_A[DT_B.melted, newCol := value]
  

Комментарии:

1. Я думаю, вам нужно будет добавить DT_B.melted[,sid:= as.numeric(sid)] после плавления, иначе он вернет ошибку (по крайней мере, для меня)

2. @DavidArenburg вы правы, но я предполагаю, что несоответствие классов — это просто ошибка в OP (т. Е. Это, Вероятно, должно быть исправлено выше по потоку, до того, как начнется плавление)

3. Вау … это работает как ветер, я не знал о функции melt … большое спасибо…