【问题标题】:Row wise operation on data.tabledata.table 上的逐行操作
【发布时间】:2014-02-12 01:18:07
【问题描述】:

假设我想逐行计算几列范围的大小。

set.seed(1)
dat <- data.frame(x=sample(1:1000,1000),
                  y=sample(1:1000,1000),
                  z=sample(1:1000,1000))

使用 data.frame(),我会做这样的事情:

dat$diff_range <- apply(dat,1,function(x) diff(range(x)))

更简单地说,我正在寻找这个操作,在每一行上:

diff(range(dat[1,]) # for i 1:nrow(dat)

如果我对整个表都这样做,它会是这样的:

setDT(dat)[,diff_range := apply(dat,1,function(x) diff(range(x)))]

但是我将如何仅对命名(或编号)行执行此操作?

【问题讨论】:

  • 这个问题听起来您想做的只是对数据框或数据表进行子集化,但根据您的个人资料,您已经知道如何做到这一点。您实际上想在这里实现什么目标?
  • 我想我的印象是我可以在apply() 表达式中使用类似于 data.table 引用列的符号。这符合我的预期:dt[,diff_range := apply(dt[,1:2,with=FALSE]...,但我认为我可以做一些魔法:apply(1:2, ...)。我想我在这里回答了我自己的问题。
  • 哦,是的,您可以,但不能以这种方式使用数据表,因为它会更改 dt 而不是制作副本。我用我最常用的方式添加了一个答案%in%

标签: r data.table


【解决方案1】:

您可以在函数之前/期间通过子集来实现。例如,如果您只想要每隔一行

dat_Diffs <- apply(dat[seq(2,1000,by=2),],1,function(x) diff(range(x)))

或者对于 1:10 的行名(因为没有指定他们的名字,所以它们只是数字递增)

dat_Diffs <- apply(dat[rownames(dat) %in% 1:10,],1,function(x) diff(range(x)))

但是为什么不先计算每行然后再计算子集呢?

【讨论】:

    【解决方案2】:

    这个怎么样:

    D[,list(I=.I,x,y,z)][,diff(range(x,y,z)),by=I][c(1:4,15:18)]
    #    I  V1
    #1:  1 971
    #2:  2 877
    #3:  3 988
    #4:  4 241
    #5: 15 622
    #6: 16 684
    #7: 17 971
    #8: 18 835
    
    #actually this will be faster
    D[c(1:4,15:18),list(I=.I,x,y,z)][,diff(range(x,y,z)),by=I]
    

    使用 .I 为您提供一个索引以使用 by= 参数调用,然后您可以在每一行上运行该函数。第二个调用按任何行号列表进行预过滤,或者如果您的真实表格看起来不同,您可以添加一个键并对其进行过滤。

    【讨论】:

    • 但是这个解决方案只有在你明确指定每列的名称时才有效,如果有太多或者你不知道它就不起作用
    【解决方案3】:

    pmaxpmin 以向量化的方式找到列中的最小值和最大值,这比单独拆分和处理每一行要好得多。它也很简洁:

    dat[, r := do.call(pmax,.SD) - do.call(pmin,.SD)]
    
    
            x   y   z   r
       1: 266 531 872 606
       2: 372 685 967 595
       3: 572 383 866 483
       4: 906 953 437 516
       5: 201 118 192  83
      ---                
     996: 768 945 292 653
     997:  61 231 965 904
     998: 771 145  18 753
     999: 841 148 839 693
    1000: 857 252 218 639
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 2020-07-18
      • 1970-01-01
      相关资源
      最近更新 更多