R: Как усреднить столбец между определёнными значениями в другом?

Вопрос или проблема

У меня есть потенциально уникальная проблема, когда я хотел бы усреднить некоторые значения в определенном столбце, используя функцию mutate() в dplyr, но только между теми строками, которые содержат определенные строки в другом столбце.

Например, у меня есть два испытуемых (Person 1 и Person 2) и три разных типа тестов (test столбец), которые они прошли. Test 1 и Test 2 — это один и тот же тест, но выполненный на разных конечностях, поэтому я хотел бы сгруппировать по каждому испытуемому (name столбец) и усреднить значения в столбце error, но только между строками, которые содержат Test 1 и Test 2. Значения error для Test 3 я хотел бы оставить нетронутыми для каждого испытуемого. Надеюсь, это имеет смысл, и любая помощь будет оценена.

set.seed(1)
dat <- data.frame(
  name = rep(paste("Person", 1:2), each = 30),
  test = rep(paste("Test", 1:3), each = 10),
  value = round(rnorm(30, 100, 20)),
  error = round(runif(30, 2, 15), 1)
  )

      name   test value error
1 Person 1 Test 1    87  13.9
2 Person 1 Test 1   104   5.8
3 Person 1 Test 1    83   8.0
4 Person 1 Test 1   132   6.3
5 Person 1 Test 1   107  10.5
6 Person 1 Test 1    84   5.4

Ответ или решение

Чтобы среднее значение столбца в одном dataframe рассчитывалось с учетом значений в другом столбце, используя функцию mutate() из пакета dplyr, вы можете следовать нижеприведенному пошаговому руководству. В этом случае мы сосредоточимся на средних значениях колонки error, но только для строк, содержащих определенные тесты (например, Test 1 и Test 2), без учета значений для Test 3.

Шаг 1: Установка необходимых библиотек

Сначала убедитесь, что библиотека dplyr установлена и загружена в вашу сессию R:

# Установка пакета, если он еще не установлен
install.packages("dplyr")

# Подключение библиотеки
library(dplyr)

Шаг 2: Создание и просмотр вашего dataframe

В данном примере создадим ваш dataframe на основе предоставленного кода:

set.seed(1)
dat <- data.frame(
  name = rep(paste("Person", 1:2), each = 30),
  test = rep(paste("Test", 1:3), each = 10),
  value = round(rnorm(30, 100, 20)),
  error = round(runif(30, 2, 15), 1)
)

# Просмотр первых строк датафрейма
head(dat)

Шаг 3: Рассчет среднего значения error для Test 1 и Test 2

Теперь, используя функцию mutate() и ifelse(), мы можем создать новый столбец, который будет содержать среднее значение ошибок для каждого из испытуемых (с учетом только Test 1 и Test 2):

# Рассчитать среднее значение для error, оставляя Test 3 неизменным
result <- dat %>%
  group_by(name) %>%
  mutate(avg_error = ifelse(test %in% c("Test 1", "Test 2"),
                             mean(error[test %in% c("Test 1", "Test 2")], na.rm = TRUE),
                             error)) %>%
  ungroup()

Шаг 4: Просмотр результата

Теперь вы можете просмотреть ваша обновленный dataframe:

# Просмотр результата
print(result)

Объяснение кода

  • group_by(name): Группируем данные по каждому субъекту.
  • mutate(): Добавляет новый столбец в dataframe. В данном случае мы используем ifelse(), чтобы проверить, является ли текущий тест Test 1 или Test 2. Если это так, мы рассчитываем среднее значение колонки error для этих тестов. mean(..., na.rm = TRUE) помогает избежать ошибок, если в данных есть пропуски (NA).
  • ungroup(): Убирает группировку, чтобы вернуть dataframe к его обычному состоянию.

Заключение

Теперь у вас есть dataframe с новым столбцом avg_error, где средние значения для error вычисляются только для Test 1 и Test 2, а строки, содержащие Test 3, остаются без изменений. Такой подход помогает обеспечить точный анализ данных и предоставляет гибкость в работе с фильтрацией и агрегацией данных в R.

Если у вас возникнут дополнительные вопросы или нужны уточнения, не стесняйтесь спрашивать!

Оцените материал
Добавить комментарий

Капча загружается...