R:将数据集中的值除以另一个值,该值在满足某些条件时会发生变化

时间:2017-02-22 20:17:23

标签: r data.table

我有一个由

生成的数据集df
df <- data.frame(
    id = seq(1:9),
    sample = c("SRM1", "SAM1", "SAM2", "SAM3", "SRM2", "SAM4", "SAM5", "SRM3", "SRM4"), 
    ratio1 = rnorm(9, mean = 2, sd = 0.02),
    ratio2 = rnorm(9, mean = 1, sd = 0.01))

看起来像

 id  sample ratio1  ratio2
 1   SRM1   2.0271  0.99915
 2   SAM1   2.0241  0.98810
 3   SAM2   1.9522  1.00300
 4   SAM3   1.9877  1.00343
 5   SRM2   1.9800  1.00522
 6   SAM4   2.0184  0.97788
 7   SAM5   2.0045  1.00549
 8   SRM3   1.9684  0.99129
 9   SRM4   2.0034  1.00310

我必须将ratio1列中SRM列中报告的值除以固定数字a = 1.9。然后,我必须将ratio1列中报告的值SAM行除以&#34;周围&#34;的平均值。 SRM/a值。

举个例子:在id 1和5,有两个SRM个样本,我计算avg1 <- mean(2.2701, 1.9800)/a。此时我可以计算

df$ratio.corr <- rep(NA, 9)
df$ratio1.corr[c(2:4)] <- df$ratio1[c(2:4)]/avg1

对于SAM4SAM5avg2将被计算为ratio1SRM2个样本的SRM3值的平均值。< / p>

对于SAM6的假设id = 10avg3将被计算为ratio1报告的值SRM4与假设{{1}之间的平均值之间的平均值带有SRM5的样本。

请考虑:

  • 真实数据集有大约10000行;
  • 始终为使用字符串id = 11; 标识的样本计算
  • avg个值
  • SRM个样本有许多不同的名称,没有共同的字符串;
  • 与连续SRM的距离可能会有所不同(有时为3行,4行甚至0行)
  • SRM列也需要类似的操作,但ratio2代替b = 0.91

这只会让我发疯。

1 个答案:

答案 0 :(得分:0)

我找到了这个可能的解决方案:

library(data.table)
a = 1.9
b = 0.91
df <- as.data.table(df)

# SRMs
srm <- grep("SRM", df$sample)
# SAMs between consecutive SRMs
sam <- diff(srm)-1

# Splitting df in SRMs and SAMs
df.srm <- df[srm][, id := 1:.N]
df.sam <- df[-srm]

# For each SAMs I write the IDs of the SRMs before and after it
srm1 <- rep(df.srm$id[-length(df.srm$id)], sam)
srm2 <- srm1 + 1
df.sam <- df.sam[, ':=' (srm1 = srm1, srm2 = srm2)]

# Calculating ratio1/a and ratio2/b
df.srm[, ':=' (ratio1.a = ratio1/a, ratio2.b = ratio2/b)]

# Calculating ratios for each SAMs divided by the average of srm1 and srm2
df.sam$ratio1.ok <- df.sam$ratio1/((df.srm$ratio1.a[df.sam$srm1] + df.srm$ratio1.a[df.sam$srm2])/2)
df.sam$ratio2.ok <- df.sam$ratio2/((df.srm$ratio2.b[df.sam$srm1] + df.srm$ratio2.b[df.sam$srm2])/2)

它似乎有效,但我认为最后两行有点混乱。你知道如何改进代码吗?