首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >data.table的重复顺序子集

data.table的重复顺序子集
EN

Code Review用户
提问于 2017-09-17 15:58:17
回答 1查看 140关注 0票数 3

我有一个很长的data.table,payoff_mat。我想按组Y选择包含列X最大值的行。这方面有几个帖子,我认为我在这方面做得很好。

令人费解的是,我想重复这个过程几次,我认为我可以做得更好。这是我剧本的热点。

这就是它的工作原理:

  1. 按组划分包含第3列最大值的行(列4-5的排列)。
  2. 第2栏按组的最大值(第4栏的排列)。
  3. 子集再按第1列的最大值计算。
代码语言:javascript
复制
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]))) ] ]

我的直觉告诉我,通过节省每一步,我会浪费大量的时间去记忆,但我对任何进步都感到满意。

我试着把它作为一个命令调用,但是没有成功地找到正确的技术来执行顺序[]调用。下面是我(目前)的最佳尝试,但很明显,它们并不等同:

代码语言:javascript
复制
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]))) ] ] 
EN

回答 1

Code Review用户

发布于 2017-09-22 19:22:34

我不是data.table专家,所以我无法判断是否有一种更快的方法,尽管https://stackoverflow.com/q/16573995/1201032建议您已经在每一步都使用高效的东西。

但是,我必须建议的更改将使代码更易于阅读和维护。首先,定义一个可以在每一步应用的函数:

代码语言:javascript
复制
max_subset <- function(dt, var, by)
  dt[dt[, .I[which.max(get(var))], by = by][,V1]]

然后,您可以按以下方式连续调用:

代码语言:javascript
复制
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包:

代码语言:javascript
复制
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(...), ..., ...)更易读。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/176308

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档