рассчитать великое среднее из средних в r - PullRequest
2 голосов
/ 30 января 2020

Я пытаюсь собрать среднее значение из средних баллов для студентов. Вот как выглядит мой набор данных:

id <-    c(1,1,1, 2,2,2, 3,3, 4,4,4)
mean <- c(5,5,5, 6,6,6, 7,7, 8,8,8)

data <- data.frame(id,mean)

> data
   id mean
1   1     5
2   1     5
3   1     5
4   2     6
5   2     6
6   2     6
7   3     7
8   3     7
9   4     8
10  4     8
11  4     8

Я использую пакет dplyr для этого расчета. Я использую это,

data %>%
  mutate(grand.mean = mean(mean))

   id mean grand.mean
1   1    5   6.454545
2   1    5   6.454545
3   1    5   6.454545
4   2    6   6.454545
5   2    6   6.454545
6   2    6   6.454545
7   3    7   6.454545
8   3    7   6.454545
9   4    8   6.454545
10  4    8   6.454545
11  4    8   6.454545

Однако, это не учитывает повторные средства для каждого идентификатора. При подсчете следует брать уникальные средства с каждого идентификатора и усреднять их. так что (5+6+7+8)/4 = 6.5 вместо 6.45.

Есть идеи? Спасибо!

Ответы [ 5 ]

3 голосов
/ 30 января 2020

Вы можете использовать unique, а затем вычислить mean, чтобы получить общее среднее .

mean(unique(data)[,"mean"])
#[1] 6.5

Или вы можете агрегировать по id, а затем вычислить mean чтобы получить общее среднее .

mean(aggregate(mean~id, data, base::mean)[,"mean"])
#[1] 6.5

Или использовать ave, чтобы получить число повторяющихся значений для id и использовать это как вес в weighted.mean.

weighted.mean(mean, 1/ave(id, id, FUN=length))
#[1] 6.5
3 голосов
/ 30 января 2020

Однострочник Base R может быть:

mean(tapply(data$mean, data$id, '[', 1))
#[1] 6.5

Чтобы поместить результат в исходный набор данных, выполните

data$grand.mean <- mean(tapply(data$mean, data$id, '[', 1))
3 голосов
/ 30 января 2020

Если есть дубликаты для mean в другом 'id', используйте match, чтобы получить позицию первого 'id' и получить mean столбца 'mean'

library(dplyr)
data %>%
     mutate(grand.mean = mean(mean[match(unique(id), id)]))
#   id mean grand.mean
#1   1    5        6.5
#2   1    5        6.5
#3   1    5        6.5
#4   2    6        6.5
#5   2    6        6.5
#6   2    6        6.5
#7   3    7        6.5
#8   3    7        6.5
#9   4    8        6.5
#10  4    8        6.5
#11  4    8        6.5

Или другой вариант: duplicated

data %>%
       mutate(grand.mean = mean(mean[!duplicated(id)]))

Или взять строки distinct. из 'id', 'mean', получите mean и свяжите столбцы с исходным набором данных

library(tidyr)
data %>% 
   distinct(id, mean) %>%
   summarise(grand.mean = mean(mean)) %>% 
   uncount(nrow(data)) %>%
   bind_cols(data, .)
2 голосов
/ 30 января 2020

Если вам нужен только один ответ для среднего значения, просто используйте два шага «суммировать» с «dplyr»:

library(dplyr)

data %>% 
  group_by(id) %>% 
  summarise(mean = mean(mean)) %>% 
  summarise(grand.mean = mean(mean))

Результат:

  grand.mean
       <dbl>
1        6.5
1 голос
/ 30 января 2020

Используя dplyr, мы можем group_by id и получить значения mean из unique mean в каждом id, затем получить grand_mean всего набора данных и выполнить right_join с исходными данными для добавления grand_mean в качестве нового столбца.

library(dplyr)

data %>%
  group_by(id) %>%
  summarise(grand_mean = mean(unique(mean))) %>%
  mutate(grand_mean = mean(grand_mean)) %>%
  right_join(data, by = 'id')

# A tibble: 11 x 3
#      id grand_mean  mean
#    <dbl>      <dbl> <dbl>
# 1     1        6.5     5
# 2     1        6.5     5
# 3     1        6.5     5
# 4     2        6.5     6
# 5     2        6.5     6
# 6     2        6.5     6
# 7     3        6.5     7
# 8     3        6.5     7
# 9     4        6.5     8
#10     4        6.5     8
#11     4        6.5     8
...