9 votes

Regrouper par, en comptant les valeurs non-NA

J'ai un dataframe qui contient un éparpillement de valeurs NA

toy_df
# Y  X1 X2 Label
# 5  3  3  A
# 3  NA 2  B
# 3  NA NA C
# 2  NA 6  B

Je veux regrouper ceci par le champ label, et compter combien de valeurs non NA il y a dans chaque variable pour chaque label.

résultat souhaité:
# Label Y  X1 X2
# A     1  1  1
# B     2  0  2
# C     1  0  0

J'ai fait cela en utilisant des boucles pour l'instant, mais c'est lent et désordonné et je suis sûr qu'il y a une meilleure façon.

Aggregate semble aller à mi-chemin, mais il inclut les NA dans le décompte.

aggregate(toy_df, list(toy_df$label), FUN=length)

Toute idée est appréciée...

13voto

akrun Points 148302

Nous pouvons utiliser data.table. Convertir le 'data.frame' en 'data.table' (setDT(toy_df)), regroupé par 'Label', parcourir le sous-ensemble de Data.table (.SD) et obtenir la sum des valeurs non NAs (!is.na(x))

library(data.table)
setDT(toy_df)[, lapply(.SD, function(x) sum(!is.na(x))), by = Label]
#   Label Y X1 X2
#1:     A 1  1  1
#2:     B 2  0  2
#3:     C 1  0  0

Ou avec dplyr en utilisant la même méthodologie

library(dplyr)
toy_df %>% 
      group_by(Label) %>%
      summarise_each(funs(sum(!is.na(.))))

Ou une option de base R avec by et colSums groupés par la 4ème colonne sur une matrice logique (!is.na(toy_df[-4]))

by(!is.na(toy_df[-4]), toy_df[4], FUN = colSums)

Ou avec rowsum avec une approche similaire à celle de by sauf en utilisant la fonction rowsum.

rowsum(+(!is.na(toy_df[-4])), group=toy_df[,4])
#  Y X1 X2
#A 1  1  1
#B 2  0  2
#C 1  0  0

2voto

G5W Points 20163

Ou en base R

aggregate(toy_df[,1:3], by=list(toy_df$Label), FUN=function(x) { sum(!is.na(x))})

1voto

aggreger(cbind(toy_df$Y, toy_df$X1, toy_df$X2), list(toy_df$label), 
          FUN = function (x) sum(!is.na(x)))

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X