Somma su più colonne con dplyr

La mia domanda riguarda la sum dei valori tra più colonne di un frame di dati e la creazione di una nuova colonna corrispondente a questa sum utilizzando dplyr . Le voci di dati nelle colonne sono binarie (0,1). Sto pensando ad un analogo filare-saggio della funzione mutate_each o mutate_each di dplyr . Di seguito è riportato un esempio minimo del frame di dati:

 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 

Potrei usare qualcosa come:

 df % mutate(sumrow= x1 + x2 + x3 + x4 + x5) 

ma ciò comporterebbe la scrittura dei nomi di ciascuna delle colonne. Mi piacciono 50 colonne. Inoltre, i nomi delle colonne cambiano a diverse iterazioni del ciclo in cui voglio implementare questa operazione, quindi vorrei evitare di dover fornire nomi di colonne.

Come posso farlo nel modo più efficiente? Qualsiasi assistenza sarebbe molto apprezzata.

Che ne dite di

riassumere ogni colonna

 df %>% replace(is.na(.), 0) %>% summarise_all(funs(sum)) 

riassumere ogni riga

 df %>% replace(is.na(.), 0) %>% mutate(sum = rowSums(.[1:5])) 

Vorrei usare la corrispondenza delle espressioni regolari per sumre le variabili con determinati nomi di pattern. Per esempio:

 df <- df %>% mutate(sum1 = rowSums(.[grep("x[3-5]", names(.))], na.rm = TRUE), sum_all = rowSums(.[grep("x", names(.))], na.rm = TRUE)) 

In questo modo puoi creare più di una variabile come sum di un determinato gruppo di variabili del tuo frame di dati.

Se vuoi sumre solo alcune colonne, userei qualcosa del genere:

 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) 

In questo modo puoi usare la dplyr::select .

Incontro spesso questo problema, e il modo più semplice per farlo è usare la funzione apply() all’interno di un comando 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)) 

Qui puoi usare qualunque cosa tu voglia selezionare le colonne usando i trucchi dplyr standard (es. starts_with() o contains() ). Eseguendo tutto il lavoro all’interno di un singolo comando mutate , questa azione può verificarsi ovunque all’interno di un stream dplyr di passaggi di elaborazione. Infine, utilizzando la funzione apply() , si ha la flessibilità di utilizzare qualsiasi sumrio necessario, inclusa la propria funzione di riepilogo appositamente creata.

In alternativa, se l’idea di utilizzare una funzione non-tidyverse non è attraente, è ansible raccogliere le colonne, riepilogarle e infine unire il risultato al frame di dati originale.

 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, . ) 

Qui ho usato la funzione starts_with() per selezionare le colonne e calcolare la sum e puoi fare quello che vuoi con i valori di NA . Lo svantaggio di questo approccio è che, sebbene sia abbastanza flessibile, non si adatta perfettamente a un stream dplyr di passaggi di pulizia dei dati.