2014-02-08 47 views
4

我试图用data.table执行一个简单的总和并按行来表示,但我得到了意想不到的结果。我在FAQ manual的第2部分中帮助data.table。我发现了一种可行的方法,但我不确定为什么FAQ中第2部分的这种方法不适用。 这种方法使我有不正确的结果(即,它给我的第一列的值):data.table中的行操作

DT [,genesum:= lapply(.SD,总和),通过基因=]

头(DT)

 gene  TCGA_04_1348  TCGA_04_1362 genesum 
    1: A1BG   0.94565   0.70585 0.94565 
    2: A1BG-AS   0.97610   1.15850 0.97610 
    3: A1CF   0.00000   0.02105 0.00000 
    4: A2BP1   0.00300   0.04150 0.00300 
    5: A2LD1   4.57975   5.02820 4.57975 
    6:  A2M   60.37320   36.09715 60.37320 

,这是给我所期望的结果

DT [,genesum:=申请(DT [, - 1,与= FALSE],1,总和)]

头(DT)

 gene  TCGA_04_1348  TCGA_04_1362 genesum 
    1: A1BG   0.94565   0.70585 1.65150 
    2: A1BG-AS   0.97610   1.15850 2.13460 
    3: A1CF   0.00000   0.02105 0.02105 
    4: A2BP1   0.00300   0.04150 0.04450 
    5: A2LD1   4.57975   5.02820 9.60795 
    6:  A2M   60.37320   36.09715 96.47035 

我有更多的列和行,这仅仅是一个子集。这与我设置密钥的方式有什么关系?

表()

NAME  NROW MB COLS              KEY                  
[1,] dt  20,785 2 gene,TCGA_04_1348_01A,TCGA_04_1362_01A,genesum   gene 

回答

2

有几件事情:

  1. dt[, genesum:=lapply(.SD,sum), by=gene]dt[, genesum:=apply(dt[,-1, with=FALSE],1, sum)]有很大的不同。

    • dt[, genesum:=lapply(.SD,sum), by=gene]环比.SD data.table并总结他们

    • dt[, genesum:=apply(dt[,-1, with=FALSE],1, sum)]被遍历行(即apply(x, 1, function)适用function每一行中x

  2. 我想你可以通过致电rowSums得到你想要的东西,就像这样:

    dt[, genesum := rowSums(dt[, -1, with=FALSE])] 
    

那是你以后?

+0

我现在看到的差别。效率方面,apply和rowSums没有区别? – sahir

+0

@sahir:我认为'rowSums'应该更快,因为我相信它避免了R中的循环,但是它也会创建一个输入副本,以便将它转换为矩阵(如果它不是已经有的话)。 –

+0

我该如何编写像rowSums这样的函数......让我们说rowMedian? – IndranilGayen

1

这里是一个替换(based on this SO question):

dt[ , genesum := sum(.SD[, -1, with=FALSE]), by = 1:NROW(dt) ] 

另一替代:

# OR... you can create a column with row positions and apply your function by row 
dt[, rowpos := .I] 
dt[ , genesum := sum(.SD[, -1, with=FALSE]), by = rowpos]