2016-08-21 33 views
1

我已经寻找数据与此类似:- [R data.table计算在其他列在多行空调

Sample.Name Marker Height Size 
1: Sample01  A 450 100 
2: Sample01  A 420 120 
3: Sample01  B 700 140 
4: Sample01  C 750 160 
5: Sample01  D 300 180 
6: Sample01  D 340 200 

其可以用下面的代码被复制:

# Some example data. 
require(data.table) 
DT <- data.table(Sample.Name=rep("Sample01", 6), 
      Marker=c("A","A","B","C","D","D"), 
      Height=c(450,420,700,750,300,340), 
      Size=c(seq(from=100, to=200,length.out = 6))) 

有一个或每个标记两行高度大小(可以是NA)。实际上,还有额外的列有等位基因值以及该例子不需要的其他信息。数据不一定按大小排序。

我想计算每个标记峰的高度(如果只有一个峰值,则为NA)之间的比率(Hb)。血红蛋白可以以几种方式来计算:

1)较小的(即更低)峰高由较大的(即,更高的)峰高

2)更短的片段由峰值高度划分的峰高除以更长的片段

3)与2)相反,但可以用与2)相同的策略来解决,所以我们不需要在这里考虑它。

我正在写一个函数,应该能够执行所有三个计算,使用data.table。到目前为止,我已经编写的代码使用两步骤的方法来计算1):

# Identify the smaller and larger peak height and count number of peaks. 
DT2 <- DT[, list(Small=min(Height), Large=max(Height), Peaks=.N), 
     by=list(Sample.Name, Marker)] 

# Divide only where there are two observed peaks. 
DT2[Peaks==2, Hb:=Small/Large, by=list(Sample.Name, Marker)] 

这生成所期望的输出:

>DT2 
    Sample.Name Marker Small Large Peaks  Hb 
1: Sample01  A 420 450  2 0.9333333 
2: Sample01  B 700 700  1  NA 
3: Sample01  C 750 750  1  NA 
4: Sample01  D 300 340  2 0.8823529 

然而,我停留在如何计算2)。我会在尺寸看,以确定哪些两个高度值分别分配给“短”与“长”。我已经咨询了data.table帮助页面和搜索计算器。远离data.table语法的专家,我一直无法找到/识别针对这个特定问题的解决方案。 2期望的输出)是与第一行除外其中血红蛋白将四百二十零分之四百五= 1.071429

回答

0

对于第二计算等同于1),就可以这样做:

DT[, .(Hb = ifelse(.N == 2, Height[Size == min(Size)]/Height[Size == max(Size)], NA_real_)) 
    , .(Sample.Name, Marker)]  # where you pick up the Height at the smaller size divided 
           # by the Height at the larger size. Note that you have to 
           # explicitly specify the NA type to be real here since data.table 
           # requires column type to be consistent 

# Sample.Name Marker  Hb 
# 1: Sample01  A 1.0714286 
# 2: Sample01  B  NA 
# 3: Sample01  C  NA 
# 4: Sample01  D 0.8823529 
+0

此解决方案效果很好!另外,我学会了如何使用'ifelse'一次性计算。谢谢! –