J'essaie de calculer les scores moyens des réponses à différents événements. Mes données sont au format long avec une ligne pour chaque événement, exemple de jeu de données data
ici:
data$average <- data%>%filter(Event == "A") %>% with(data, (R1 + R2 + R3)/4)
Donc, pour obtenir la moyenne de l'événement A, ce serait (R1 + R2 + R3) / 3 en ignorant le N / A, alors que l'événement B a 4 réponses. J'ai calculé la moyenne de l'événement A dans dplyr
comme suit:
Subject Event R1 R2 R3 R4 Average 1 A 1 2 2 N/A 2.5 1 B 1 1 1 1 1
J'ai rencontré des problèmes lorsque j'ai essayé de faire de même pour le prochain événement. .Merci pour votre aide!
4 Réponses :
Vous n'avez pas besoin de filtrer pour chaque événement à la fois. dplyr
est capable de traiter toutes les lignes à la fois, une par une. De plus, lorsque vous utilisez dplyr
, vous n'avez pas besoin d'assigner à une variable en dehors de son contexte, comme data $ average . Vous pouvez utiliser
mutate ()
. La syntaxe intuitive de dplyr
serait donc: data <-
data %>%
mutate(average = mean(c(R1, R2, R3, R4), na.rm = TRUE))
Je pense que votre na.rm = TRUE
doit vivre en dehors du vecteur.
Ce qui suit n'inclut pas la valeur NA dans le cadre du calcul de la moyenne ( na.rm = TRUE ). De plus, je pense que le regroupement par événement est important. Lorsqu'ils sont exécutés sans group_by, les calculs combinent tous les événements et la valeur résultante est 1.285714 (= 9/7 obs).
Subject Event R1 R2 R3 R4 Average <dbl> <fct> <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 A 1 2 2 NA 1.67 2 1 B 1 1 1 1 1
Sortie:
data <- data.frame( Subject=c(1,1), Event=c('A', 'B'), R1=c(1,1), R2=c(2,1), R3=c(2,1), R4=c(NA,1) ) df <- data %>% group_by(Event) %>% mutate(Average = mean(c(R1,R2,R3,R4), na.rm=TRUE))
Vous pouvez utiliser rowMeans
pour calculer les moyennes pour chaque ligne d'un dataframe. Spécifiez dans l'entrée les colonnes que vous souhaitez inclure. Pour ignorer le NA
, définissez na.rm=TRUE
.
data$Average <- rowMeans(data[,grep("R",names(data))], na.rm=TRUE)
Si vous aviez beaucoup de colonnes à faire la moyenne et que vous ne vouliez pas saisissez-les tous, vous pouvez utiliser grep
pour faire correspondre les noms des données
à n'importe quel modèle. Disons par exemple que vous voulez faire la moyenne de toutes les lignes contenant un "R" dans leur nom:
data$Average <- rowMeans(data[,c("R1", "R2", "R3", "R4")], na.rm=TRUE)
Juste pour compléter toutes les réponses précédentes, si vous avez plusieurs valeurs nommées R1
, R2
, .... R100
, au lieu d'écrire tous dans la fonction mean
, vous pourriez être intéressé en remodelant votre dataframe dans un format plus long en utilisant la fonction pivot_longer
, puis en les groupant par événement et en calculant la moyenne. Enfin, en utilisant pivot_wider
, vous pourriez obtenir votre dataframe dans le format initial plus large.
structure(list(Subject = c(1L, 1L), Event = c("A", "B"), R1 = c(1L, 1L), R2 = 2:1, R3 = 2:1, R4 = c("N/A", "1"), Average = c(2.5, 1)), row.names = c(NA, -2L), class = c("data.table", "data.frame" ), .internal.selfref = <pointer: 0x5555743c1310>)
Comme mentionné par @TTS, il y a quelque chose qui ne va pas dans votre calcul de la moyenne de l'événement A.
Exemple reproductible
library(dplyr) library(tidyr) df %>% mutate_at(vars(contains("R")), as.numeric) %>% pivot_longer(cols = starts_with("R"), names_to = "R", values_to = "Values") %>% group_by(Event) %>% mutate(average = mean(Values, na.rm = TRUE)) %>% pivot_wider(names_from = R, values_from = Values) # A tibble: 2 x 8 # Groups: Event [2] Subject Event Average average R1 R2 R3 R4 <int> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 A 2.5 1.67 1 2 2 NA 2 1 B 1 1 1 1 1 1