2014-03-26 24 views
3

很久以前我已经问过这个问题,但还没有找到答案。我不知道这是否合法在stackoverflow,但我转发它。findInterval()在data.table中有不同的间隔R

我在R中有一个data.table,我想创建一个新的列,查找相应年份/月份的每个价格的时间间隔。

重复的例子:

set.seed(100) 
DT <- data.table(year=2000:2009, month=1:10, price=runif(5*26^2)*100) 
intervals <- list(year=2000:2009, month=1:10, interval = sort(round(runif(9)*100))) 
intervals <- replicate(10, (sample(10:100,100, replace=T))) 
intervals <- t(apply(intervals, 1, sort)) 
intervals.dt <- data.table(intervals) 
intervals.dt[, c("year", "month") := list(rep(2000:2009, each=10), 1:10)] 
setkey(intervals.dt, year, month) 
setkey(DT, year, month) 

我刚才想:

  • 合并DTintervals.dt data.tables按月/年,
  • 创建一个新的intervalsstring列由所有的V *列到 一列字符串,(不是很优雅,我承认),最后
  • 它substringing为载体,所以我可以在findInterval()使用它,但该解决方案并不为每个行工作

所以,后(!):

DT <- merge(DT, intervals.dt) 
DT <- DT[, intervalsstring := paste(V1, V2, V3, V4, V5, V6, V7, V8, V9, V10)] 
DT <- DT[, c("V1", "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10") := NULL] 
DT[, interval := findInterval(price, strsplit(intervalsstring, " ")[[1]])] 

我得到

> DT 
     year month  price    intervalsstring interval 
    1: 2000  1 30.776611 12 21 36 46 48 51 63 72 91 95  2 
    2: 2000  1 62.499648 12 21 36 46 48 51 63 72 91 95  6 
    3: 2000  1 53.581115 12 21 36 46 48 51 63 72 91 95  6 
    4: 2000  1 48.830599 12 21 36 46 48 51 63 72 91 95  5 
    5: 2000  1 33.066053 12 21 36 46 48 51 63 72 91 95  2 
---                
3376: 2009 10 33.635924 12 40 45 48 50 65 75 90 96 97  2 
3377: 2009 10 38.993769 12 40 45 48 50 65 75 90 96 97  3 
3378: 2009 10 75.065820 12 40 45 48 50 65 75 90 96 97  8 
3379: 2009 10 6.277403 12 40 45 48 50 65 75 90 96 97  0 
3380: 2009 10 64.189162 12 40 45 48 50 65 75 90 96 97  7 

这是正确的第一行,但而不是为最后(或其他)行。 例如,对于第3380行,价格〜64.19应该在第5个区间而不是第7个区间。我想我的错误是,通过我的最后一个命令,找到间隔只依赖intervalsstring的第一行。

谢谢!

+0

你看过'?data.table'并确保你理解每一个参数吗?我只是简单地看了一下这个问题,我的第一个想法是想知道你是否知道'roll','',也许''foverlaps()'。 –

回答

8

你的主要问题是你没有为每个组做findInterval。但我也没有看到将这个大型合并data.tablepaste/strsplit业务的重点。这是我会做的:

DT[, interval := findInterval(price, 
           intervals.dt[.BY][, V1:V10, with = F]), 
    by = .(year, month)][] 
#  year month  price interval 
# 1: 2000  1 30.776611  2 
# 2: 2000  1 62.499648  6 
# 3: 2000  1 53.581115  6 
# 4: 2000  1 48.830599  5 
# 5: 2000  1 33.066053  2 
# ---        
#3376: 2009 10 33.635924  1 
#3377: 2009 10 38.993769  1 
#3378: 2009 10 75.065820  7 
#3379: 2009 10 6.277403  0 
#3380: 2009 10 64.189162  5 

请注意,intervals.dt[.BY]是一个键控子集。

+1

不错'.BY'的例子。添加到https://github.com/Rdatatable/data.table/issues/1363。 –