#r #dplyr
Вопрос:
summarise_if
Функция очень полезна для суммирования нескольких переменных. Предположим, что мне нужно среднее значение каждой числовой переменной в моем наборе данных. Я могу использовать
df <- as_tibble(iris)
df %>% summarise_if(is.numeric, .fun = mean)
Это прекрасно работает. Но предположим теперь , что функция in .fun
включает в себя 2 аргумента из набора данных (примером может служить weighet.mean
, где весовой переменной является Sepal.Длина). Я пытался,
df %>% summarise_if(is.numeric, .fun = function(x, w) weighted.mean(x, w), w = Sepal.Length)
Ошибка заключалась в
Ошибка в списке 2(…) : объект ‘разделен.Ширина» не найдена
Я подозреваю, что R искал не Sepal.Length
в df
глобальной среде, а в ней. Поэтому я должен использовать,
df %>% summarise_if(is.numeric, .fun = function(x, w) weighted.mean(x, w), w = df$Sepal.Length)
Это работает, но это не очень хорошо, чтобы делать df$Sepal.Длина. Например, для меня становится совершенно невозможным вычислить средневзвешенное значение по группам.
df %>% group_by(Species) %>% summarise_if(is.numeric, .fun = function(x, w) weighted.mean(x, w), w = df$Sepal.Length)
Ошибка: Проблема с
summarise()
колонкойSepal.Length
.
ℹSepal.Length = (function (x, w) ...
.
x ‘x’ и » w » должны иметь одинаковую длину
ℹ Ошибка произошла в группе 1: Вид = сетоза.
Итак, как использовать summarise_if
или summarise_at
с функциями, включающими две переменные из набора данных.
Ответ №1:
Если нам нужно использовать Sepal.Length
as w
, объедините ( c
) вывод where(is.numeric)
и укажите -Sepal.Length
, из чего следует удалить столбец across
, а затем используйте weighted.mean
для других числовых столбцов с w
помощью as ‘Sepal.Длина’
library(dplyr)
df %>%
summarise(across(c(where(is.numeric), -Sepal.Length),
~ weighted.mean(., w = Sepal.Length)))
# A tibble: 1 × 3
Sepal.Width Petal.Length Petal.Width
<dbl> <dbl> <dbl>
1 3.05 3.97 1.29
Или сгруппированный был бы
df %>%
group_by(Species) %>%
summarise(across(c(where(is.numeric), -Sepal.Length),
~ weighted.mean(., w = Sepal.Length)))
-выход
# A tibble: 3 × 4
Species Sepal.Width Petal.Length Petal.Width
<fct> <dbl> <dbl> <dbl>
1 setosa 3.45 1.47 0.248
2 versicolor 2.78 4.29 1.34
3 virginica 2.99 5.60 2.03
ПРИМЕЧАНИЕ: _if
, _at
, _all
функции суффиксов устарели в пользу across
Комментарии:
1. Большое спасибо. Я не знал, и я все еще использую их. Просто вопрос, почему — перед сепалом.длина
2. @Ari.stat просто для того, чтобы удалить этот столбец из взвешенного значения.в противном случае и x, и w будут разделены. Длина для этого столбца
3. Что, если мне снова понадобится третья переменная-имя?
4. то есть
df %>% group_by(Species) %>% summarise(across(c(where(is.numeric), -c(Sepal.Length, Sepal.Width)), ~ weighted.mean(., w = Sepal.Length)))
5. Или это может быть вектор имен, т. е.
nm1 <- names(df)[1:2];df %>% group_by(Species) %>% summarise(across(c(where(is.numeric), -all_of(nm1)), ~ weighted.mean(., w = Sepal.Length)))