Подведите итог с пользовательской функцией при вызове значений вне группы - PullRequest
0 голосов
/ 15 апреля 2020

Я пытаюсь суммировать несколько столбцов, используя summarize_at() с пользовательской функцией. Часть, на которой я застрял, - это функция ssmd(), предназначенная для получения вектора значений из группы, установленной group_by(), и другого вектора значений вне этой группы.

В приведенном ниже примере x должен быть вектором для каждого набора значений на Month (зависит от текущей группы), а y должен быть фиксированным набором значений для Month == 5.

# custom function
ssmd <- function(x, y){
  (mean(x, na.rm = TRUE) - mean(y, na.rm = TRUE)) / sqrt(var(x, na.rm = TRUE) + var(y, na.rm = TRUE))
}

# dataset
d <- airquality

# this isn't working - trying to find the difference between the mean for each Month and the mean of Month 5, for columns Ozone, Solar.R, Wind, and Temp
d %>%
  group_by(Month) %>%
  summarize_at(vars(Ozone:Temp), funs(ssmd, x = ., y = .[Month == 5])) %>%
  ungroup()

На данный момент это дает следующую ошибку: Error in mean(y, na.rm = TRUE) : argument "y" is missing, with no default. Поэтому я думаю, что у меня есть синтаксическая ошибка, в дополнение к тому, что я застрял в том, как получить доступ к значениям вне текущей группы.

Ожидаемый результат - это фрейм данных с одной строкой для каждого месяца и одним столбцом для каждой переменной. (Озон, Солнечный. R, Ветер и Температура).

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Есть две проблемы:

1) Когда вы ссылаетесь на Month в funs, это только для этой группы, а не для всего фрейма данных

2) 1) Может быть разрешено с помощью .$Month, но у вас нет доступа ко всему столбцу в summarize_at для поднабора только тех значений, где Month == 5.

Однако вам не нужна эта пользовательская функция, вы можете взять mean всех столбцов для каждого Month и затем вычесть значения из каждого столбца, где Month = 5.

library(dplyr)

d %>%
  group_by(Month) %>%
  summarize_at(vars(Ozone:Temp), mean, na.rm = TRUE) %>%
  mutate_at(vars(Ozone:Temp), ~.  - .[Month == 5])

# A tibble: 5 x 5
#  Month Ozone Solar.R  Wind  Temp
#  <int> <dbl>   <dbl> <dbl> <dbl>
#1     5  0       0     0      0  
#2     6  5.83    8.87 -1.36  13.6
#3     7 35.5    35.2  -2.68  18.4
#4     8 36.3    -9.44 -2.83  18.4
#5     9  7.83  -13.9  -1.44  11.4

Для использования функции ssmd в обновленном сообщении мы можем сделать:

library(dplyr)
library(purrr)

named_info <- d %>% select(Ozone:Temp) %>% names()

map(named_info, function(x) d %>% group_by(Month) %>% 
                     summarise_at(vars(x), ~ssmd(., d[[x]][d$Month == 5]))) %>%
    reduce(inner_join, by = 'Month')
1 голос
/ 15 апреля 2020

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

library(dplyr)

d <- airquality

d1 <- d %>%
  group_by(Month) %>%
  summarize_at(vars(Ozone:Temp), list(~mean(., na.rm = TRUE))) %>%
  ungroup()

d1[-1] <- lapply(d1[-1], function(x) x - x[1])

d1
# # A tibble: 5 x 5
#   Month Ozone Solar.R  Wind  Temp
#   <int> <dbl>   <dbl> <dbl> <dbl>
# 1     5  0       0     0      0  
# 2     6  5.83    8.87 -1.36  13.6
# 3     7 35.5    35.2  -2.68  18.4
# 4     8 36.3    -9.44 -2.83  18.4
# 5     9  7.83  -13.9  -1.44  11.4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...