Somme sur plusieurs colonnes avec dplyr
Ma question consiste à additionner les valeurs sur plusieurs colonnes d'une trame de données et à créer une nouvelle colonne correspondant à cette sommation en utilisant dplyr
. Les entrées de données dans les colonnes sont binaires (0,1). Je pense à un analogue en ligne de la fonction summarise_each
ou mutate_each
de dplyr
. Voici un exemple minimal de la trame de données:
library(dplyr)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
> df
x1 x2 x3 x4 x5
1 1 1 0 1 1
2 0 1 1 0 1
3 0 NA 0 NA NA
4 NA 1 1 1 1
5 0 1 1 0 1
6 1 0 0 0 1
7 1 NA NA NA NA
8 NA NA NA 0 1
9 0 0 0 0 0
10 1 1 1 1 1
Je pourrais utiliser quelque chose comme:
df <- df %>% mutate(sumrow= x1 + x2 + x3 + x4 + x5)
, Mais cela impliquerait d'écrire les noms de chacune des colonnes. J'ai comme 50 colonnes. Dans en outre, les noms de colonne changent à différentes itérations de la boucle dans laquelle je veux implémenter ceci ainsi, je voudrais essayer d'éviter d'avoir à donner de noms de colonnes.
Comment puis-je le faire le plus efficacement? Toute aide serait grandement appréciée.
4 réponses
Que diriez-vous de
Additionnez chaque colonne
df %>%
replace(is.na(.), 0) %>%
summarise_all(funs(sum))
Additionnez chaque ligne
df %>%
replace(is.na(.), 0) %>%
mutate(sum = rowSums(.[1:5]))
J'utiliserais la correspondance d'expression régulière pour additionner des variables avec certains noms de motif. Par exemple:
df <- df %>% mutate(sum1 = rowSums(.[grep("x[3-5]", names(.))], na.rm = TRUE),
sum_all = rowSums(.[grep("x", names(.))], na.rm = TRUE))
De cette façon, vous pouvez créer plus d'une variable en tant que somme de certains groupes de variables de votre trame de données.
Si vous voulez additionner certaines colonnes seulement, j'utiliserais quelque chose comme ceci:
library(dplyr)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
df %>% select(x3:x5) %>% rowSums(na.rm=TRUE) -> df$x3x5.total
head(df)
De cette façon, vous pouvez utiliser la syntaxe de dplyr::select
.
Je rencontre souvent ce problème, et la façon la plus simple de le faire est d'utiliser la fonction apply()
dans une commande mutate
.
library(tidyverse)
df=data.frame(
x1=c(1,0,0,NA,0,1,1,NA,0,1),
x2=c(1,1,NA,1,1,0,NA,NA,0,1),
x3=c(0,1,0,1,1,0,NA,NA,0,1),
x4=c(1,0,NA,1,0,0,NA,0,0,1),
x5=c(1,1,NA,1,1,1,NA,1,0,1))
df %>%
mutate(sum = select(., x1:x5) %>% apply(1, sum, na.rm=TRUE))
Ici, vous pouvez utiliser ce que vous voulez pour sélectionner les colonnes en utilisant les astuces standard dplyr
(par exemple starts_with()
ou contains()
). En effectuant tout le travail dans une seule commande mutate
, cette action peut se produire n'importe où dans un flux dplyr
d'étapes de traitement. Enfin, en utilisant la fonction apply()
, vous avez la possibilité d'utiliser le résumé dont vous avez besoin, y compris votre propre but construit fonction de résumé.
Alternativement, si l'idée d'utiliser une fonction non-tidyverse n'est pas attrayante, alors vous pouvez rassembler les colonnes, les résumer et enfin joindre le résultat à la trame de données d'origine.
df <- df %>% mutate( id = 1:n() ) # Need some ID column for this to work
df <- df %>%
group_by(id) %>%
gather('Key', 'value', starts_with('x')) %>%
summarise( Key.Sum = sum(value) ) %>%
left_join( df, . )
Ici, j'ai utilisé la fonction starts_with()
pour sélectionner les colonnes et calculer la somme et vous pouvez faire ce que vous voulez avec des valeurs NA
. L'inconvénient de cette approche est qu'il est assez souple, il ne rentre pas vraiment dans un dplyr
flux de données étapes de nettoyage.