Вопрос или проблема
Когда я тестирую расчеты для каждой строки, функция суммы выдает результаты правильно, в то время как данные для функции среднего значения берутся только из первого столбца. Я не совсем понимаю причину этого……
library(tidyverse)
data <- tibble(
x = as.numeric(1:9 *50),
y = as.numeric(10:18),
z = as.numeric(-10:-2)
)
data %>%
mutate(sum = pmap_dbl(.,sum),
mean = pmap_dbl(.,mean))
# A tibble: 9 × 5
x y z sum mean
<dbl> <dbl> <dbl> <dbl> <dbl>
1 50 10 -10 50 50
2 100 11 -9 102 100
3 150 12 -8 154 150
4 200 13 -7 206 200
5 250 14 -6 258 250
6 300 15 -5 310 300
7 350 16 -4 362 350
8 400 17 -3 414 400
9 450 18 -2 466 450
Может кто-то помочь объяснить эту ситуацию?
Подпись функции base::sum()
– это sum(..., na.rm = FALSE)
, где ...
– это значения для суммы. Она будет вычислять сумму всех предоставленных аргументов, если они не называются na.rm
, например:
sum(1, 2) # 3
sum(2, countme = 3) # 5
С другой стороны, подпись функции для base::mean()
– это mean(x, ...)
, где x является вектором значений, например:
mean(1,2,3) # интерпретируется как mean(x = 1, trim = 0, na.rm = FALSE, 2, 3)
# [1] 1
mean(c(1,2,3))
# [1] 1
purrr::pmap_chr()
передает аргументы отдельно. Если мы возьмем, например, вашу вторую строку, то происходит следующее:
sum(100, 11, -9)
# [1] 102
mean(100, 11, -9)
# [1] 100
Это потому, что ваш вызов функции интерпретируется как mean(100)
. ...
предназначен для дополнительных аргументов, передаваемых в другие методы или из них, и в этом случае они игнорируются.
Что вы хотите сделать во втором случае – это следующее:
mean(c(100, 11, -9))
# [1] 34
Поскольку вы уже вычисляете сумму, вы можете использовать это для вычисления среднего, например.
data %>%
mutate(
sum = rowSums(.),
mean = sum / ncol(.)
)
# # A tibble: 9 × 5
# x y z sum mean
# <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 50 10 -10 50 16.7
# 2 100 11 -9 102 34
# 3 150 12 -8 154 51.3
# 4 200 13 -7 206 68.7
# 5 250 14 -6 258 86
# 6 300 15 -5 310 103.
# 7 350 16 -4 362 121.
# 8 400 17 -3 414 138
# 9 450 18 -2 466 155.
Пока пользователь SamR объясняет причину, я предложу альтернативный вариант. Просто выполните
> transform(d0, sum = rowSums(d0), mean = rowMeans(d0))
x y z sum mean
1 50 10 -10 50 16.66667
2 100 11 -9 102 34.00000
3 150 12 -8 154 51.33333
4 200 13 -7 206 68.66667
5 250 14 -6 258 86.00000
6 300 15 -5 310 103.33333
7 350 16 -4 362 120.66667
8 400 17 -3 414 138.00000
9 450 18 -2 466 155.33333
где d0
– это ваши данные. Без дополнительных пакетов.
Ответ или решение
При анализе результатов выполнения функции pmap_dbl
в вашем коде, важно понимать, как работают функции sum
и mean
, а также, как purrr::pmap
передает аргументы в эти функции. Давайте разберем вашу задачу более подробно, чтобы прояснить ситуацию.
Проблема описания
Вы упомянули, что при вычислении суммы с помощью функции sum
все работает корректно, но результаты для функции mean
выглядят странными — они отображают значение только из первого столбца. Это действительно так, и причина кроется в различии в том, как эти функции обрабатывают аргументы.
Анализ поведения функций
-
Функция
sum
:
Функцияsum
принимает произвольное количество аргументов:sum(..., na.rm = FALSE)
Она складывает все значения, переданные в аргументах, что делает ее удобной для работы с различными входными данными.
-
Функция
mean
:
Напротив, функцияmean
принимает вектор значений:mean(x, ...)
Таким образом, если вы передадите несколько отдельных значений, как это делает
pmap
,mean
будет интерпретировать это какmean(x = первое значение)
и проигнорирует остальные. Это и объясняет, почему вы получаете значение только первого столбца.
Примеры работы функций
Рассмотрим ситуацию с конкретными данными из вашего примера:
data %>%
mutate(sum = pmap_dbl(., sum),
mean = pmap_dbl(., mean))
Для строки:
x = 100
,y = 11
,z = -9
sum(100, 11, -9)
выдает102
mean(100, 11, -9)
интерпретируется какmean(100)
и дает100
Правильное использование
Если целью является вычисление среднего арифметического для всех столбцов, рекомендуется использовать mean
как:
mean(c(x, y, z))
Однако так как вы уже вычисляете сумму, можно использовать следующий подход для нахождения среднего:
data %>%
mutate(sum = rowSums(.),
mean = sum / ncol(.))
Это даст вам правильные значения среднего, избегая проблем с интерпретацией аргументов.
Альтернативный подход
Вы также можете использовать функцию rowMeans
, которая специально разработана для вычисления среднего по строкам матриц или таблиц:
data %>%
mutate(sum = rowSums(.),
mean = rowMeans(.))
Это упростит ваш код и будет более читабельно.
Заключение
Работа с pmap
для различных функций требует понимания того, как именно они обрабатывают передаваемые аргументы. Разграничение этих понятий, а также использование более подходящих функций, таких как rowSums
и rowMeans
, поможет вам избежать подобных проблем в будущем. Используйте эти навыки и подходы для повышения эффективности вашего кода в R
и облегчи работу с данными.