Как рассчитать среднее экспериментальных значений повторностей одного и того же образца, не зная заранее количество повторений?

У меня есть файл csv с набором данных экспериментальных значений многих образцов, а иногда и копий одного и того же образца. Для повторов я учитываю только среднее значение повторов, принадлежащих одной и той же выборке. Проблема в том, что количество повторов разное, может быть 2, 3, 4 и т.д...

Мой код неверен, потому что он должен работать только в том случае, если число реплик равно 2 (поскольку я использую цикл для сравнения одного идентификатора образца с предыдущим идентификатором образца в цикле). Кроме того, мой код не работает, он добавляет одно и то же среднее значение ко всем моим образцам, что неправильно. Я думаю, что есть проблема в начале цикла тоже. Потому что, когда x=1, x-1=0, что не соответствует никакому значению, это может привести к тому, что код не будет работать? Я новичок в R, у меня никогда не было курсов или тренингов, я учусь, чтобы изучить его самостоятельно, поэтому заранее спасибо за вашу помощь.

Мой набор данных:

введите здесь описание изображения

Ожидаемый результат:

введите здесь описание изображения

PS: в этом примере количество повторов равно 2. Однако оно может быть разным в зависимости от образцов, иногда 2, иногда 3, 4 и т.д...

for (x in length(dat$Sample)){
  if (dat$Sample[x]==dat$Sample[x-1]){
    dat$Average.OD[x-1] <- mean(dat$OD[x], dat$OD[x-1])
    dat$Average.OD[x] <- NA
  }
}

person Armelle Quinn    schedule 19.07.2019    source источник
comment
Привет, Амели, можете ли вы прикрепить образец набора данных, над которым вы работаете, и окончательный результат, который вы ожидаете?   -  person ealbsho93    schedule 19.07.2019
comment
for (x in length(dat$Sample)) повторяется только один раз, когда x равно length(dat$Sample), должно быть 2:length(dat$Sample). Также: посмотрите, является ли это тем, что вам нужно.   -  person Rui Barradas    schedule 19.07.2019
comment
Попробуйте ave(dat$Sample, dat$Sample, FUN = mean, na.rm = TRUE) или tapply(dat$Sample, dat$Sample, FUN = mean, na.rm = TRUE)   -  person Rui Barradas    schedule 19.07.2019


Ответы (2)


Позвольте мне показать вам возможное решение с помощью data.table.

#Data
data <- data.frame('Sample'=c('Blank','Blank','STD1','STD1'), 
                             'OD'=c(0.07,0.08,0.09,0.10))

#Code
#Converting our data to data.table.
setDT(data)

#Finding the average of OD by Sample Column. Here Sample Column is the key.If you want it by both Sample and Replicates, pass both of them in by and so on.
data[, AverageOD := mean(OD), by = c("Sample")]

#Turning all the duplicate AverageOD values to NA.
data[duplicated(data, by = c("Sample")), AverageOD := NA] 

#Turning column name of AverageOD to  Average OD
names(data)[which(names(data) == "AverageOD")] = 'Average OD'

Дайте знать, если у вас появятся вопросы.

person ealbsho93    schedule 22.07.2019
comment
Это работает отлично, спасибо! Однако у меня уже есть столбец в CSV-файле для Average_OD. Я попытался использовать ваш код, изменив AverageOD на Average OD, который является именем столбца, который у меня есть в моем файле, и появляется это сообщение об ошибке: Error in [.data.table(data, , :=(Average OD, mean(OD)), by = c("Sample")) : Type of RHS ('double') must match LHS ('logical'). To check and coerce would impact performance too much for the fastest cases. Either change the type of the target column, or coerce the RHS of := yourself (e.g. by using 1L instead of 1) - person Armelle Quinn; 23.07.2019
comment
Мне удалось избежать вышеуказанной ошибки, просто оставив AverageOD, который добавил мне новый столбец, затем я заменил столбец, который у меня есть в моем файле, используя data$Average OD <- data$AverageOD , затем я удалил новый столбец, используя data$AverageOD <- NULL. Это правильный способ справиться с такой ситуацией? - person Armelle Quinn; 23.07.2019
comment
Кроме того, не могли бы вы объяснить, почему вы использовали :=, а не =, например? Я не могу найти много информации о его использовании. Спасибо. - person Armelle Quinn; 23.07.2019
comment
Привет, Амель! Я прикрепил обновленный код для назначения среднего значения OD в качестве имени столбца. := — это специальный оператор, который мы можем использовать для создания нового столбца при агрегировании значений в data.table по группам. Пожалуйста, посмотрите на шпаргалку data.table для большего количества применений. Между тем, если это решение работает для вас, подтвердите ответ. Спасибо. - person ealbsho93; 23.07.2019
comment
Привет @ealbsho93, Возможно ли вместо введения в новый столбец (AverageOD) просто добавить рассчитанное среднее значение к уже существующему в наборе данных? Спасибо за помощь. - person Armelle Quinn; 24.07.2019
comment
Привет, Армель. Поиск этого может занять больше времени, чем исходное решение. :) Дайте мне знать, если это абсолютно необходимо. - person ealbsho93; 24.07.2019
comment
На самом деле это необходимо, потому что я работаю с обновляемой базой данных, поэтому в предыдущем примере среднее значение уже рассчитано и указано в столбце. Пожалуйста, дайте мне знать, если вы думаете о чем-то. Спасибо - person Armelle Quinn; 26.07.2019

Вы можете сделать это без циклов, используя aggregate и merge. Поскольку вы не приводите никаких данных, поясню на простом примере.

## Example data
set.seed(123)
Sample = round(runif(10), 1)
OD = sample(4, 10, replace=T)
dat = data.frame(OD, Sample)

Means = aggregate(dat$Sample, list(dat$OD), mean, na.rm=T)
names(Means) = c("OD", "mean")
Means
  OD      mean
1  1 0.9000000
2  2 0.7000000
3  3 0.3666667
4  4 0.4000000

merge(dat, Means, "OD")
   OD Sample      mean
1   1    0.9 0.9000000
2   1    0.9 0.9000000
3   2    0.8 0.7000000
4   2    0.9 0.7000000
5   2    0.4 0.7000000
6   3    0.0 0.3666667
7   3    0.6 0.3666667
8   3    0.5 0.3666667
9   4    0.3 0.4000000
10  4    0.5 0.4000000
person G5W    schedule 19.07.2019
comment
Спасибо за ваш ответ. Мне пришлось внести некоторые коррективы, но ваш код работает. Means <- aggregate(dat$OD, list(dat$Sample), mean, na.rm = T) names(Means) = c("Sample", "Mean_OD") merge(dat, Means, by = "Sample") Что касается слияния, оно распечатывает только значения в пространстве консоли R. Я хотел бы, чтобы значения были добавлены в столбец, который уже существует в моем фрейме данных. Это возможно? Если да, то какую функцию следует использовать? - person Armelle Quinn; 22.07.2019