在R中聚合超过80K的唯一ID

roo*_*ody 6 r data.table

关于大数据的另一个新手问题.我正在使用带有时间序列数据的大型数据集(3.5米行).我想创建一个data.table列,找到第一次出现唯一标识符的列.

df是a data.table, df$timestamp是类中的日期POSIXct,df$id是唯一的数字标识符.我正在使用以下代码:

# UPDATED - DATA KEYED
setkey(df, id)
sub_df<-df[,(min(timestamp)), by=list(id)] # Finding first timestamp for each unique ID
Run Code Online (Sandbox Code Playgroud)

这是捕获.我正在聚合超过80k的唯一ID.R很窒息.我能做些什么来优化我的方法?

Aru*_*run 6

这里有一些代码来测试哪种行为需要很多时间

require(data.table)
dt <- data.table(sample(seq(as.Date("2012-01-01"), as.Date("2013-12-31"), 
          by="days"), 1e5, replace=T), val=sample(1e4, 1e5, replace = T))

FUN1 <- function() {
    out <- dt[, min(dt$V1), by=val]  # min of entire V1 for each group i.e. wrong
}

FUN2 <- function() {
    out <- dt[, min(V1), by=val]     # min of V1 within group as intended
}

require(rbenchmark)
> benchmark(FUN1(), FUN2(), replications = 1, order="elapsed")
#     test replications elapsed relative user.self sys.self user.child sys.child
# 2 FUN2()            1   0.271    1.000     0.242    0.002          0         0
# 1 FUN1()            1  38.378  141.616    32.584    4.153          0         0
Run Code Online (Sandbox Code Playgroud)

很明显,这FUN2()是快速的.请记住,在这两种情况下,都没有设置KEY

  • 德勤!对于后代,在操作之前使用`setkey`对函数进行基准测试与您的`FUN2`相同. (2认同)

Jus*_*tin 5

正如@Arun所提到的,真正的密钥(没有双关语)是使用正确的data.table语法而不是setkey.

df[, min(timestamp), by=id]
Run Code Online (Sandbox Code Playgroud)

虽然80k独特的ID听起来很多,但使用它的key功能data.table可以使它成为一个可管理的前景.

setkey(df, id)
Run Code Online (Sandbox Code Playgroud)

然后像以前一样处理.对于它的价值,您通常可以使用键的令人愉快的副作用,即分类.

set.seed(1)
dat <- data.table(x = sample(1:10, 10), y = c('a', 'b'))

    x y
 1:  3 a
 2:  4 b
 3:  5 a
 4:  7 b
 5:  2 a
 6:  8 b
 7:  9 a
 8:  6 b
 9: 10 a
10:  1 b

setkey(dat, y, x)

     x y
 1:  2 a
 2:  3 a
 3:  5 a
 4:  9 a
 5: 10 a
 6:  1 b
 7:  4 b
 8:  6 b
 9:  7 b
10:  8 b
Run Code Online (Sandbox Code Playgroud)

然后,min另一个更复杂的函数只是一个子集操作:

dat[, .SD[1], by=y]
Run Code Online (Sandbox Code Playgroud)