我有一个很长的data.table,payoff_mat。我想按组Y选择包含列X最大值的行。这方面有几个帖子,我认为我在这方面做得很好。
令人费解的是,我想重复这个过程几次,我认为我可以做得更好。这是我剧本的热点。
这就是它的工作原理:
library(data.table)
library(iterpc)
set.seed(1)
I<-iterpc(table(rnorm(5)),3, ordered=TRUE,replace=FALSE)
support_n <-getnext(I,d=180) # not real size. Larger in practice.
payoff_n <-matrix(rnorm(180), ncol = 3) # not real size. Larger in practice.
payoff_mat<-cbind(payoff_n,support_n)
payoff_mat<-data.table(payoff_mat)
#My current solution: eval(parse(text = ....)) is long but seems to be the standard best syntax for data.table in these cases.
cn<-colnames(payoff_mat) #need column names, data.table does not like using column number.
step_1<-payoff_mat[payoff_mat[ ,.I[ which.max(eval(parse(text = cn[3]))) ] , by = eval(cn[4:5]) ][,V1]] #
step_2<-step_1[step_1[ ,.I[ which.max(eval(parse(text = cn[2]))) ] , by = eval(cn[4:4]) ][,V1]]
step_3<-step_2[ ,.SD[ which.max(eval(parse(text = cn[1]))) ] ]我的直觉告诉我,通过节省每一步,我会浪费大量的时间去记忆,但我对任何进步都感到满意。
我试着把它作为一个命令调用,但是没有成功地找到正确的技术来执行顺序[]调用。下面是我(目前)的最佳尝试,但很明显,它们并不等同:
payoff_mat [payoff_mat[ ,.I[ which.max(eval(parse(text = cn[3]))) ] , by = eval(cn[4:5]) ][,V1]] [payoff_mat[ ,.I[ which.max(eval(parse(text = cn[2]))) ] , by = eval(cn[4:4]) ][,V1]] [ ,.SD[ which.max(eval(parse(text = cn[1]))) ] ] 发布于 2017-09-22 19:22:34
我不是data.table专家,所以我无法判断是否有一种更快的方法,尽管https://stackoverflow.com/q/16573995/1201032建议您已经在每一步都使用高效的东西。
但是,我必须建议的更改将使代码更易于阅读和维护。首先,定义一个可以在每一步应用的函数:
max_subset <- function(dt, var, by)
dt[dt[, .I[which.max(get(var))], by = by][,V1]]然后,您可以按以下方式连续调用:
step <- payoff_mat
step <- max_subset(step, "V3", c("V4", "V5"))
step <- max_subset(step, "V2", c("V4"))
step <- max_subset(step, "V1", c())或者使用magrittr包:
library(magrittr)
payoff_mat %>% max_subset("V3", c("V4", "V5")) %>%
max_subset("V2", c("V4")) %>%
max_subset("V1", c()) -> step3请注意,在第一种方法(step <- ...)中将中间输出分配给变量不应该占用任何时间(请随意测试)。您的代码将比使用嵌套调用:max_subset(max_subset(max_subset(...), ..., ...)更易读。
https://codereview.stackexchange.com/questions/176308
复制相似问题