2017-02-22 2 views
0

У меня есть набор данных df порожденныхR: значения Разделить в наборе данных по другому значению, которое изменяется при соблюдении некоторых условий

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 строк по среднему значению «окружающих» значений 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 

Для SAM4 и SAM5, avg2 будет рассчитываться как среднее из значений ratio1 для SRM2 и SRM3 образцов.

Для гипотетического SAM6 с id = 10, avg3 будет рассчитываться как среднее между значениями ratio1 для зарегистрированных SRM4 и гипотетического SRM5 образца с т.е. id = 11.

Пожалуйста, обратите внимание, что:

  • реальный набор данных имеет около 10000 строк;
  • avg значения всегда рассчитываются для образцов, идентифицированных со строкой SRM;
  • non-SRM образцы имеют много разных наименований без общей строки;
  • расстояние от последовательного SRM может изменяться (иногда 3, 4 или даже 0 строки) требуются
  • подобные операции также для ratio2 колонка, но с b = 0.91 вместо a.

Это просто сводит меня с ума.

ответ

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) 

Это, кажется, работает, но я думаю, что последние две строки немного беспорядок. Вы знаете, как улучшить код?

Смежные вопросы