【问题标题】:R data.table subsetting within a group and splitting a data table into twoR data.table 分组内的子集并将数据表分成两个
【发布时间】:2013-08-16 04:09:26
【问题描述】:

我有以下data.table。

ts,id
1,a
2,a
3,a
4,a
5,a
6,a
7,a
1,b
2,b
3,b
4,b

我想将此 data.table 分成两个子集。标准是每个组的前半部分(在本例中为“id”列)在一个数据表中,其余部分在另一个 data.table 中。所以预期的结果是两个data.tables如下

ts,id
1,a
2,a
3,a
4,a
1,b
2,b

 ts,id
 5,a
 6,a
 7,a
 3,b
 4,b

我尝试了以下,

z1 = x[,.SD[.I < .N/2,],by=dev]
z1

得到以下结果

id ts
a  1
a  2
a  3

不知何故,.SD 中的 .I 并没有按照我认为的方式工作。任何帮助表示赞赏。 提前致谢。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    .I 给出相对于整个 data.table 的行位置。因此它不能在.SD 中那样使用。

    类似

    DT[, subset := seq_len(.N) > .N/2,by='id']
    
    subset1 <- DT[(subset)][,subset:=NULL]
    subset2 <- DT[!(subset)][,subset:=NULL]
    
    subset1
    #    ts id
    # 1:  4  a
    # 2:  5  a
    # 3:  6  a
    # 4:  7  a
    # 5:  3  b
    # 6:  4  b
    subset2
    #   ts id
    # 1:  1  a
    # 2:  2  a
    # 3:  3  a
    # 4:  1  b
    # 5:  2  b
    

    应该工作

    对于超过 2 个组,您可以使用 cut 创建具有适当级别数的因子

    类似

     DT[, subset := cut(seq_len(.N), 3, labels= FALSE),by='id']
     # you could copy to the global environment a subset for each, but this 
     # will not be memory efficient!
     list2env(setattr(split(DT, DT[['subset']]),'names', paste0('s',1:3)), .GlobalEnv)
    

    【讨论】:

    • @mnel .I.N 可以用在.SD,只要用对了,看我的帖子
    • @eddi -- 确实如此。很好的发现。
    【解决方案2】:

    这是你的表达的更正版本:

    dt[, .SD[, .SD[.I <= .N/2]], by = id]
    #   id ts
    #1:  a  1
    #2:  a  2
    #3:  a  3
    #4:  b  1
    #5:  b  2
    

    你的不工作的原因是因为.I.Ni-expression中不可用(即[的第一个参数),所以父data.table.I和@987654328使用@(即dt's)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      相关资源
      最近更新 更多