Для-l oop для суммирования и присоединения по dplyr - PullRequest
0 голосов
/ 11 февраля 2020

Вот мой упрощенный df:

GP_A <- c(rep("a",3),rep("b",2),rep("c",2))
GP_B <- c(rep("d",2),rep("e",4),rep("f",1))
GENDER <- c(rep("M",4),rep("F",3))
LOC <- c(rep("HK",2),rep("UK",3),rep("JP",2))
SCORE <- c(50,70,80,20,30,80,90)
df <- as.data.frame(cbind(GP_A,GP_B,GENDER,LOC,SCORE))

> df

GP_A GP_B GENDER LOC SCORE
1    a    d      M  HK    50
2    a    d      M  HK    70
3    a    e      M  UK    80
4    b    e      M  UK    20
5    b    e      F  UK    30
6    c    e      F  JP    80
7    c    f      F  JP    90

Я хочу суммировать счет по GP_A, GP_B или другим столбцам группировки, которые не показаны в этом примере. Поскольку число столбцов группировки может составлять до 50, я решил использовать for-l oop для суммирования баллов.

Оригинальный метод суммирует баллы с 1 группой по одному:

GP_A_SCORE <- df %>% group_by(GP_A,GENDER,LOC) %>% summarize(SCORE=mean(SCORE))
GP_B_SCORE <- df %>% group_by(GP_B,GENDER,LOC) %>% summarize(SCORE=mean(SCORE))
...

То, что я хочу, это использовать for-l oop следующим образом (невозможно запустить):

GP_list <- c("GP_A","GP_B",...)
LOC_list <- c("HK","UK","JP",...)
SCORE <- list()
for (i in GP_list){
    for (j in LOC_list){
SCORE[[paste0(i,j)]] <- df %>% group_by(i,j,GENDER) %>% summarize(SCORE=mean(SCORE))
}}

Как и в «group_by ()», переменные классифицируются как символьные, и здесь отображаемая ошибка:

Ошибка: столбец I, J неизвестен

Есть ли способ заставить R распознать переменную?

Я сталкиваюсь с той же проблемой в left_join dplyr.

Ошибка отображается, когда я делал что-то вроде: left_join(x,y,by=c(i=i)) внутри al oop.

Ответы [ 2 ]

2 голосов
/ 11 февраля 2020

Вы можете получить данные в длинном формате и затем вычислить mean

library(dplyr)
library(tidyr)

df %>%
  pivot_longer(cols = starts_with('GP')) %>%
  group_by(GENDER ,LOC, name, value) %>%
  summarise(SCORE = mean(SCORE))

#   GENDER LOC   name  value SCORE
#   <fct>  <fct> <chr> <fct> <dbl>
# 1 F      JP    GP_A  c        85
# 2 F      JP    GP_B  e        80
# 3 F      JP    GP_B  f        90
# 4 F      UK    GP_A  b        30
# 5 F      UK    GP_B  e        30
# 6 M      HK    GP_A  a        60
# 7 M      HK    GP_B  d        60
# 8 M      UK    GP_A  a        80
# 9 M      UK    GP_A  b        20
#10 M      UK    GP_B  e        50
1 голос
/ 11 февраля 2020

Мы можем использовать melt из data.table

library(data.table)
melt(setDT(df), measure = patterns("^GP"))[, .(SCORE = mean(SCORE)),
      .(GENDER, LOC, variable, value)]

данные

df <- data.frame(GP_A,GP_B,GENDER,LOC,SCORE)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...