создать столбец на основе поиска значений строк в другой data.table - PullRequest
1 голос
/ 04 марта 2020

Я могу легко взломать это, но мне было интересно, как это сделать data.table. Upvote для dplyr тоже.

У меня есть два data.table s, такие как

   this that year
1:    5    a 2016
2:    6    b 2016
3:    7    c 2017
4:    8    d 2018

и

       this that Mkt.2016 Mkt.2017 Mkt.2018
    1:    5    a       51       52       53
    2:    5    b       61       62       63
    3:    6    a       71       72       73
    4:    6    b       81       82       83
    5:    7    c       91       92       93
    6:    8    d      101      102      103
    7:    9    e      111      112      113

, и я хочу найти значение в соответствующий столбец. Результатом будет

   this that year valueForYear
1:    5    a 2016           51
2:    6    b 2016           81
3:    7    c 2017           92
4:    8    d 2018          103

выходов для таблиц:

dt1 <- structure(list(this = 5:8, that = c("a", "b", "c", "d"), year = c(2016L, 
2016L, 2017L, 2018L)), row.names = c(NA, -4L), class = c("data.table", 
"data.frame"))

dt2 <- structure(list(this = c(5L, 5L, 6L, 6L, 7L, 8L, 9L), that = c("a", 
"b", "a", "b", "c", "d", "e"), Mkt.2016 = c(51L, 61L, 71L, 81L, 
91L, 101L, 111L), Mkt.2017 = c(52L, 62L, 72L, 82L, 92L, 102L, 
112L), Mkt.2018 = c(53L, 63L, 73L, 83L, 93L, 103L, 113L)), row.names = c(NA, 
-7L), class = c("data.table", "data.frame"))

Ответы [ 3 ]

3 голосов
/ 04 марта 2020

Другая опция data.table

dt1[, .(value = unlist(dt2[this==This & that==That, .SD, 
      .SDcols = paste0('Mkt.', year)])), by = .(This=this, That=that, year)]

#    This That year value
# 1:    5    a 2016    51
# 2:    6    b 2016    81
# 3:    7    c 2017    92
# 4:    8    d 2018   103

Или, более кратко,

dt2[dt1][, setnames(.SD[,.SD, .SDcols=paste0('Mkt.', year)],1,'Value'), .(this,that,year)]
#    this that year Value
# 1:    5    a 2016    51
# 2:    6    b 2016    81
# 3:    7    c 2017    92
# 4:    8    d 2018   103
2 голосов
/ 04 марта 2020

Мы можем melt отформатировать «long», а затем выполнить объединение. Использование только data.table методов в качестве входных объектов также data.table

library(data.table)
v1 <- melt(dt2, id.var = c('this','that'))[dt1, 
        .(value[year == sub("Mkt\\.", "", variable)]), on = .(this, that)]$V1
dt1[, valueForYear := v1]
dt1
#   this that year valueForYear
#1:    5    a 2016           51
#2:    6    b 2016           81
#3:    7    c 2017           92
#4:    8    d 2018          103
1 голос
/ 04 марта 2020

A dplyr можно получить dt2 в длинном формате, используя pivot_longer и присоединиться dt1.

library(dplyr)

dt2  %>%
  tidyr::pivot_longer(cols = -c(this, that), 
                      names_to = c(".value", "year"), 
                      names_sep = "\\.") %>%
   type.convert(as.is  = TRUE) %>%
   right_join(dt1, by = c('this', 'that', 'year'))

# A tibble: 4 x 4
#   this that   year   Mkt
#  <int> <chr> <int> <int>
#1     5 a      2016    51
#2     6 b      2016    81
#3     7 c      2017    92
#4     8 d      2018   103
.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...