скажем, у меня есть кадр данных в R, похожий на этот:
setValue <- rep(seq(0,20,10), each=3)
readValue <- rep(1:length(setValue))
df <- data.frame(setValue, readValue)
В результате данные выглядят так:
setValue readValue
1 0 1
2 0 2
3 0 3
4 10 4
5 10 5
6 10 6
7 20 7
8 20 8
9 20 9
Я хочу добавить новый столбец срезультат функции, основанной на группе, определенной setValue
.Я использую функцию median
для этого примера.
Результат будет таким:
setValue readValue median
1 0 1 2
2 0 2 2
3 0 3 2
4 10 4 5
5 10 5 5
6 10 6 5
7 20 7 8
8 20 8 8
9 20 9 8
Решение
Лучшее, о чем я мог подумать, это R-yfiedfor-loop () с использованием sapply
.Для каждой строки извлекается subset
из df
, где текущий setValue
строки равен setValue
исходного кадра данных df
.
df$median <- sapply(1:nrow(df), function(row) {
median( subset(df$readValue, df$setValue == df[row,]$setValue) )
})
Сокращение вычислений
Чтобы избежать подгруппировки и повторного вычисления медианы в каждой строке, я могу предварительно рассчитать медиану для данного setValue
, используя aggregate
:
df_median <- aggregate(. ~ setValue, data=df, FUN=median)
В результате получается кадр данных со значениями медианы вreadValue
:
В результате:
setValue readValue
1 0 2
2 10 5
3 20 8
Вместо этого используйте предварительно рассчитанные медианные значения в функции:
df$median <- sapply(1:nrow(df4), function(row) {
subset(df_median$readValue, df_median$setValue == df[row,]$setValue)
})
Вопрос
Есть ли более эффективный способ сделать это?