#r #dplyr
Вопрос:
У меня есть набор данных, похожий на тот, что приведен ниже, со 100 строками. Я хочу усреднить баллы учащихся по годам и школе. Таким образом, у меня будет один балл за 1 доллар США в 2019 году и 1 доллар США в 2020 году и т. Д. Для этого я использую этот код.
df <- df %>%
group_by(Year, `School Name`) %>%
summarise(across(everything(), .f = list(mean = mean), na.rm = TRUE))
Но мне нужно среднее число n. Я хочу знать, сколько студентов получили средний балл. Как мне это сделать с NAs?
Год | Название школы | Оценка Учащихся | Оценка Учащихся |
---|---|---|---|
2019 | ISD 1 | 1 | NA |
2020 | ISD 4 | 4 | 2 |
2020 | ISD 3 | NA | 3 |
2018 | ISD 1 | 4 | NA |
2019 | ISD 4 | 2 | 5 |
2020 | ISD 4 | 3 | 2 |
2019 | ISD 3 | NA | 1 |
2018 | ISD1 | 2 | 4 |
Комментарии:
1. используйте
summarise(n = n(), Mean = mean(
Оценку), Sum = sum(
студента Оценка))
студента, если вам нужна только одна колонка2. добавил некоторый контекст. У меня есть NAs в файле, о котором я забыл, и есть несколько столбцов оценок. Поэтому мне нужно найти среднее значение для каждого столбца, но также нужно n подсчетов
3. Вы можете использовать
summarise(n = n(), across(all_of(yourcols), mean, na.rm = TRUE), across(all_of(othercols), sum, na.rm = TRUE))
n
Это было бы то же самое, верно? Таким образом, вы можете использовать это за пределамиacross
4. Что
Student Score
представляют собой различные столбцы? Хотите суммировать каждый из них отдельно или в одну колонку?
Ответ №1:
Если я правильно понял, это может вам помочь
#Libraries
library(tidyverse)
library(lubridate)
#Data
df <-
tibble::tribble(
~Year, ~School.Name, ~Student.Score1, ~Student.Score2,
2019L, "ISD 1", 1L, NA,
2020L, "ISD 4", 4L, 2L,
2020L, "ISD 3", NA, 3L,
2018L, "ISD 1", 4L, NA,
2019L, "ISD 4", 2L, 5L,
2020L, "ISD 4", 3L, 2L,
2019L, "ISD 3", NA, 1L,
2018L, "ISD 1", 2L, 4L
)
#How to
df %>%
group_by(Year,School.Name) %>%
summarise(
n = n(),
across(.cols = contains(".Score"),.fns = function(x)mean(x,na.rm = TRUE))
)
# A tibble: 6 x 5
# Groups: Year [3]
Year School.Name n Student.Score1 Student.Score2
<int> <chr> <int> <dbl> <dbl>
1 2018 ISD 1 2 3 4
2 2019 ISD 1 1 1 NaN
3 2019 ISD 3 1 NaN 1
4 2019 ISD 4 1 2 5
5 2020 ISD 3 1 NaN 3
6 2020 ISD 4 2 3.5 2
Ответ №2:
Я предполагаю Student Score
, что столбцы представляют отдельных студентов, на которых следует смотреть в сочетании с другими студентами из той же школы и того же года. Если это так, то вам, вероятно, следует сначала преобразовать свои данные в длинный формат, как показано ниже:
library(dplyr); library(tidyr)
df %>%
# reshape, keeping Year and School Name as keys
pivot_longer(-c(Year, `School.Name`)) %>%
group_by(Year, `School.Name`) %>%
filter(!is.na(value)) %>%
summarise(mean = mean(value),
n = n(), .groups = "drop")
Результат
Year School.Name mean n
<int> <chr> <dbl> <int>
1 2018 ISD 1 4 1
2 2018 ISD1 3 2
3 2019 ISD 1 1 1
4 2019 ISD 3 1 1
5 2019 ISD 4 3.5 2
6 2020 ISD 3 3 1
7 2020 ISD 4 2.75 4
(Обратите внимание, я использовал данные как есть, но я подозреваю, что «ISD 1» и «ISD1» должны быть одним и тем же, и в этом случае вам может потребоваться сначала выполнить некоторую очистку данных.)
Исходные данные: (Обратите внимание, что столбцы оценок учащихся с уникальными именами переименовываются data.frame
функцией, чтобы иметь уникальные имена, например, Студент.Оценка и Студент.Оценка.1)
df <- data.frame(
stringsAsFactors = FALSE,
Year = c(2019L, 2020L, 2020L, 2018L, 2019L, 2020L, 2019L, 2018L),
`School Name` = c("ISD 1","ISD 4","ISD 3",
"ISD 1","ISD 4","ISD 4","ISD 3","ISD1"),
`Student Score` = c(1L, 4L, NA, 4L, 2L, 3L, NA, 2L),
`Student Score` = c(NA, 2L, 3L, NA, 5L, 2L, 1L, 4L)
)
Ответ №3:
Более длительное вращение может быть хорошим подходом.
df %>%
pivot_longer(cols = c(-Year, -`School Name`)) %>%
group_by(Year, `School Name`) %>%
summarise(mean = mean(value, na.rm = T))
выход
# A tibble: 6 x 3
# Groups: Year [3]
Year `School Name` mean
<int> <chr> <dbl>
1 2018 ISD 1 3.33
2 2019 ISD 1 1
3 2019 ISD 3 1
4 2019 ISD 4 3.5
5 2020 ISD 3 3
6 2020 ISD 4 2.75