У меня есть данные об уловах рыбы. Каждая строка содержит название вида, значение улова (cpue) и некоторые другие несвязанные поля идентификации (год, местоположение, глубина и т. д.). Этот код создаст набор данных с правильной структурой:
# a sample dataset
set.seed(1337)
fish = rbind(
data.frame(
spp = "Flounder",
cpue = rnorm(5, 5, 2)
),
data.frame(
spp = "Bass",
cpue = rnorm(5, 15, 1)
),
data.frame(
spp = "Cod",
cpue = rnorm(5, 2, 4)
)
)
Я пытаюсь создать нормализованный столбец cpue cpue_norm
. Для этого я применяю следующую функцию к каждому значению cpue:
cpue_norm = (cpue - cpue_mean)/cpue_std
Где cpue_mean
и cpue_std
— это, соответственно, среднее значение и стандартное отклонение cpue
. Предостережение заключается в том, что мне нужно сделать это по каждому виду, т. е. когда я вычисляю cpue_norm
для конкретной строки, мне нужно вычислить cpue_mean
и cpue_std
, используя cpue
из только этого разновидность.
Проблема в том, что все виды находятся в одном наборе данных. Поэтому для каждой строки мне нужно рассчитать среднее значение и стандартное отклонение cpue для этого вида, а затем использовать эти значения для вычисления cpue_norm.
Я смог добиться некоторого прогресса с tapply:
calc_cpue_norm = function(l) {
return((l - mean(l))/sd(l))
}
tapply(fish$cpue, fish$spp, calc_cpue_norm)
но я получаю списки, когда мне нужно вместо этого добавлять эти значения в строки фрейма данных.
Любой, кто знает R лучше меня, может поделиться мудростью?
fish <- fish %>% dplyr::group_by(spp) %>% dplyr::mutate(cpue_norm = (cpue - mean(cpue, na.rm = TRUE)) / sd(cpue, na.rm = TRUE))
- person Claudiu Papasteri   schedule 22.02.2021as.data.table(fish)[, cpue_norm := (cpue - mean(cpue))/sd(cpue), by = .(spp)]
; основание R:ave(fish$cpue, fish$spp, FUN = function(z) (z-mean(z))/sd(z))
; а у вас dplyr сверху. - person r2evans   schedule 22.02.2021