【问题标题】:create column based on lookup of row values onto another data.table根据将行值查找到另一个 data.table 来创建列
【发布时间】:2020-03-03 23:59:24
【问题描述】:

我可以轻松破解它,但想知道正确的 data.table 方法是什么。 也为dplyr 投票。

我有两个data.tables 喜欢

   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"))

【问题讨论】:

    标签: r dplyr data.table


    【解决方案1】:

    另一个 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】:

      我们可以将melt 转换为“长”格式,然后进行连接。仅使用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
      

      【讨论】:

        【解决方案3】:

        dplyr 方法是使用pivot_longer 以长格式获取dt2 并加入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
        

        【讨论】:

          猜你喜欢
          • 2015-12-24
          • 2023-02-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-11-27
          • 1970-01-01
          相关资源
          最近更新 更多