【问题标题】:R data.table findInterval() with varying intervalsR data.table findInterval() 具有不同的间隔
【发布时间】:2014-03-01 19:33:27
【问题描述】:

我在 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,
  • 创建一个包含所有 V* 列的新 intervalsstring 列以 一列字符串,(我承认不是很优雅),最后
  • 将其子串为向量,以便我可以在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 的第一行。

谢谢!

【问题讨论】:

    标签: r data.table intervals


    【解决方案1】:

    您必须向我们提供参数 by = year 才能将函数应用于所有子集:

    DT[, interval := findInterval(price, intervals[as.character(year), ]), by = year]
    
          year     price interval
       1: 2000 30.776611        4
       2: 2001 25.767250        1
       3: 2002 55.232243        4
       4: 2003  5.638315        0
       5: 2004 46.854928        2
      ---                        
    3376: 2005 97.497761       10
    3377: 2006 50.141227        5
    3378: 2007 50.186270        7
    3379: 2008 99.229338       10
    3380: 2009 64.189162        8
    

    更新(基于已编辑的问题):

    DT[ , interval := findInterval(price, 
                                   unlist(intervals.dt[J(year[1], month[1]), 1:10])), 
       by = c("year", "month")]
          year month     price V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 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
    

    【讨论】:

    • 非常感谢 Sven!... 你能帮我扩展一下吗?假设我也有几个月......那我该怎么办?
    • @user2383408 你有月和年的区间矩阵吗?请澄清。
    • 感谢您的快速回复,我已相应编辑(希望)我的问题。
    • 嗯,...非常感谢您的回复,但更新不起作用...例如使用我的种子我得到&gt; DT (the end)3377: 2006 7 50.141227 53378: 2007 8 50.186270 5应该是: 3377: 2006 7 50.141227 3 3378: 2007 8 50.186270 4 我注意到intervals.dt[J(year[1], month[1]), 1:10, with = FALSE]intervals.dt[J(year[1], month[2]), 1:10, with = FALSE] 不同,但与intervals.dt[J(year[2], month[1]), 1:10, with = FALSE] 没有不同...
    • @user2383408 感谢您的指出。我会的,看看问题。
    猜你喜欢
    • 2014-05-05
    • 2012-11-09
    • 2020-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-07
    • 1970-01-01
    • 2013-04-05
    相关资源
    最近更新 更多