作者:萌萌美人鱼 | 来源:互联网 | 2022-12-01 17:15
我的问题与这个问题非常相似:
如何提取每个组的前n行?
dt
date age name val
1: 2000-01-01 3 Andrew 93.73546
2: 2000-01-01 4 Ben 101.83643
3: 2000-01-01 5 Charlie 91.64371
4: 2000-01-02 6 Adam 115.95281
5: 2000-01-02 7 Bob 103.29508
6: 2000-01-02 8 Campbell 91.79532
我们有一个dt
,我添加了一个名为的额外列val
。首先,我们要提取每个组中的前n行。提供的链接中的解决方案是:
dt[, .SD[1:2], by=date] # where 1:2 is the index needed
dt[dt[, .I[1:2], by = date]$V1] # for speed
我的问题是,如果该函数取决于子集信息,那么该如何将函数应用于每个组的前n行。我正在尝试应用这样的事情:
# uses other columns for results/ is dependent on subsetted rows
# but keep it simple for replication
do_something <- function(dt){
res <- ifelse(cumsum(dt$val) > 200, 1, 0)
return(res)
}
# first 2 rows of dt by group=date
x <- dt[, .SD[1:2], by=date]
# apply do_something to first 2 rows of dt by group=date
x[, list('age'=age,'name'=name,'val'=val, 'funcVal'= do_something(.SD[1:2])),by=date]
date age name val funcVal
1: 2000-01-01 3 Andrew 93.73546 0
2: 2000-01-01 4 Ben 101.83643 1
3: 2000-01-02 6 Adam 115.95281 0
4: 2000-01-02 7 Bob 103.29508 1
我要解决这个错误吗?有没有更有效的方法可以做到这一点?我似乎无法弄清楚如何为此应用“速度”解决方案。有没有一种方法,而不必先保存子集结果并立即按日期将函数应用于前两行?
感谢您的任何帮助,下面是产生上面数据的代码:
date <- c("2000-01-01","2000-01-01","2000-01-01",
"2000-01-02","2000-01-02","2000-01-02")
age <- c(3,4,5,6,7,8)
name <- c("Andrew","Ben","Charlie","Adam","Bob","Campbell")
val <- val <- rnorm(6,100,10)
dt <- data.table(date, age, name,val)
Frank..
5
如果分组列不止一个,则将其折叠为一个可能更有效:
m = dt[, .(g = .GRP, r = .I[1:2]), by = date]
dt[m$r, v := ff(.SD), by=m$g, .SDcols="val"]
这只是@eddi方法(保持行号.I
,在@akrun的答案中可见)的扩展,它也保持组计数器.GRP
。
Re OP的评论是,他们更关注功能,好吧,从@akrun借用,有...
ff = function(x) as.integer(cumsum(x[[1]]) > 200)
假设所有值均为非负数,则可以在C语言中更有效地进行处理,因为一旦达到阈值,累积和就可以停止。不过,对于两行的特殊情况,这无关紧要。
我的印象是,这是一个伪函数,因此毫无意义。我通常想到的许多效率改进取决于功能和数据。
1> Frank..:
如果分组列不止一个,则将其折叠为一个可能更有效:
m = dt[, .(g = .GRP, r = .I[1:2]), by = date]
dt[m$r, v := ff(.SD), by=m$g, .SDcols="val"]
这只是@eddi方法(保持行号.I
,在@akrun的答案中可见)的扩展,它也保持组计数器.GRP
。
Re OP的评论是,他们更关注功能,好吧,从@akrun借用,有...
ff = function(x) as.integer(cumsum(x[[1]]) > 200)
假设所有值均为非负数,则可以在C语言中更有效地进行处理,因为一旦达到阈值,累积和就可以停止。不过,对于两行的特殊情况,这无关紧要。
我的印象是,这是一个伪函数,因此毫无意义。我通常想到的许多效率改进取决于功能和数据。