R:使用data.table和self-join按组进行首次观察

Bra*_*rad 16 r self-join data.table

我正在尝试使用data.table通过一组三个变量获得最高行.

我有一个有效的解决方案:

col1 <- c(1,1,1,1,2,2,2,2,3,3,3,3)
col2 <- c(2000,2000,2001,2001,2000,2000,2001,2001,2000,2000,2001,2001)
col4 <- c(1,2,3,4,5,6,7,8,9,10,11,12)
data <- data.frame(store=col1,year=col2,month=12,sales=col4)

solution1 <- data.table(data)[,.SD[1,],by="store,year,month"]
Run Code Online (Sandbox Code Playgroud)

我使用Matthew Dowle在以下链接中建议的较慢方法:

https://stats.stackexchange.com/questions/7884/fast-ways-in-r-to-get-the-first-row-of-a-data-frame-grouped-by-an-identifier

我正在尝试实现更快的自联接但无法使其工作.

有没有人有什么建议?

mne*_*nel 23

选项1(使用键)

设置密钥 store, year, month

DT <- data.table(data, key = c('store','year','month'))
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用unique创建包含键列的唯一值的data.table.默认情况下,这将采用第一个条目

unique(DT)
   store year month sales
1:     1 2000    12     1
2:     1 2001    12     3
3:     2 2000    12     5
4:     2 2001    12     7
5:     3 2000    12     9
6:     3 2001    12    11
Run Code Online (Sandbox Code Playgroud)

但是,可以肯定的是,你可以使用自联接mult='first'.(其他选项是'all''last')

# the key(DT) subsets the key columns only, so you don't end up with two 
# sales columns
DT[unique(DT[,key(DT), with = FALSE]), mult = 'first']
Run Code Online (Sandbox Code Playgroud)

选项2(无键)

如果没有设置按键,这将是更快地使用.I.SD

DTb <- data.table(data)
DTb[DTb[,list(row1 = .I[1]), by = list(store, year, month)][,row1]]
Run Code Online (Sandbox Code Playgroud)

  • +1也是.对于像这样的任务,我略微偏爱`.I`,但是语法咬了,因为讨厌的组列被包含在结果中(当添加`drop`时会更好).还有一个FR使自然的`DT [,.SD [1],by ="store,year,month"]`快速工作而不会使用`.SD`([FR#2330](https: //r-forge.r-project.org/tracker/index.php?func=detail&aid=2330&group_id=240&atid=978),所以将来这将是'选择top n*from`或`select的独特方式来自......等等 (2认同)