簡體   English   中英

在匹配來自第二個表的數據時,在`data.table`中創建向量列的最有效方法是什么?

[英]What is the most efficient way to create a column of vectors in `data.table` when matching data from a second table?

data.table中創建向量列的最有效方法是data.table ,我們需要匹配第二個data.table中的元素。

例如,給出下面的兩個data.tables

   > A_ids.DT        > rec_data_table
      name id           bid counts names_list
   1:    A  1        1: 301     21        C,E
   2:    B  2        2: 302     21          E
   3:    C  3        3: 303      5      H,E,G
   4:    D  4        4: 304     10        H,D
   5:    F  6        5: 305      3          E
   6:    G  7        6: 306      5          G
   7:    H  8        7: 307      6        B,C
   8:    J 10        
   9:    K 11        

我想在rec_data_table中創建一個新列,其中每個元素都是來自A_ids.DT的id的列表,如rec_data_table[,names_list]所引用的

重要信息: names_list每個條目中表示的順序必須反映在新列中。 即:對於第3:3:H, E, G )我們應該得到c(8, NA, 7)

以下一行使用了sapply作品,但我質疑它的效率。
是否有更好的(即更快,更優雅)替代品? (注意實際數據是幾行100K)

rec_data_table[, A_IDs.list := sapply(names_list, function(n) c(A_ids.DT[n, id]$id))]

   bid counts names_list A_IDs.list
1: 301     21        C,E       3,NA
2: 302     21          E         NA
3: 303      5      H,E,G     8,NA,7
4: 304     10        H,D        8,4
5: 305      3          E         NA
6: 306      5          G          7
7: 307      6        B,C        2,3


#--------------------------------------------------#
#           SAMPLE DATA                            #

library(data.table)
set.seed(101)

  rows <- size <- 7
  varyingLengths <- c(sample(1:3, rows, TRUE))
  A <-  lapply(varyingLengths, function(n) sample(LETTERS[1:8], n))
  counts <- round(abs(rnorm(size)*12))   
rec_data_table <- data.table(bid=300+(1:size), counts=counts, names_list=A, key="bid")

A_ids.DT <- data.table(name=LETTERS[c(1:4,6:8,10:11)], id=c(1:4,6:8,10:11), key="name")

也許解壓縮列表,然后加入整個表,然后重新打包?

tmp <- setkey(rec_data_table[, list(names = names_list[[1]],
                                    orig.order = seq_along(names_list[[1]])),
                             by = list(bid, counts)], names)
tmp <- A_ids.DT[tmp]
setkey(tmp, orig.order)
tmp <- tmp[, list(names_list = list(name), A_IDs.list = list(id)),
           by = list(bid, counts)]

# Rearrange to sample output order
setkey(tmp, bid)
setcolorder(tmp, c("bid", "counts", "names_list", "A_IDs.list"))


### Output###
> tmp
#   bid counts names_list A_IDs.list
# 1: 301     21        C,E       3,NA
# 2: 302     21          E         NA
# 3: 303      5      H,E,G     8,NA,7
# 4: 304     10        H,D        8,4
# 5: 305      3          E         NA
# 6: 306      5          G          7
# 7: 307      6        B,C        2,3

> identical(tmp, rec_data_table[, A_IDs.list := sapply(names_list, function(n) c(A_ids.DT[n, id]$id))])
# [1] TRUE

計時

我增加了行數rec_data_table1e5 ,得到了以下的時機。

提出的方法:

> system.time(rec_data_table[, A_IDs.list := sapply(names_list, function(n) c(A_ids.DT[n, id]$id))])
   user  system elapsed 
 196.89    0.04  197.81 

這里介紹的方法:

> system.time( {
+ tmp <- setkey(rec_data_ta .... [TRUNCATED] 
   user  system elapsed 
   0.95    0.00    0.95 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM