Добавление столбца в фрейм данных на основе подмножества того же фрейма данных - PullRequest
0 голосов
/ 18 декабря 2018

скажем, у меня есть кадр данных в 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)

})

Вопрос

Есть ли более эффективный способ сделать это?

Ответы [ 2 ]

0 голосов
/ 18 декабря 2018

A data.table способ:

library(data.table)

setDT(df)[, median := median(readValue), by = setValue]

Выход:

   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
0 голосов
/ 18 декабря 2018

Используйте ave от основания R:

transform(df, median = ave(readValue, setValue, FUN = median))

или используйте dplyr:

library(dplyr)
df %>%
  group_by(setValue) %>%
  mutate(median = median(readValue)) %>%
  ungroup
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...