J'ai un dataframe df avec un UserId en double où généralement au moins une ligne des colonnes correspondantes A, B, C n'est pas vide. Les colonnes A, B, C contiennent des valeurs et des dates NA. Mon objectif est de rassembler toutes les lignes non vides (et NA si la colonne entière de cet ID utilisateur est NA) pour le même ID utilisateur sur une seule ligne.
J'ai essayé d'utiliser group_by () et filter () pour les valeurs nonNA mais le le résultat est une trame de données vide. Je sais que le code ci-dessous nécessite quelques modifications pour obtenir le résultat souhaité, mais je n'ai pas pu le comprendre.
df2 UserID A B C 1 1 2018-09-20 18:00:55 2018-09-20 18:00:42 2018-09-20 18:00:38 2 2 2018-09-20 18:00:55 2018-09-20 18:00:55 2018-09-20 18:00:40 3 4 2018-09-20 18:00:49 2018-09-20 18:00:49 <NA> 4 5 <NA> <NA> 2018-09-20 18:00:49
df2<-df %>% group_by(UserID) %>% filter(!is.na(A), !is.na(B), !is.na(C))
3 Réponses :
Nous pouvons rassembler
le dataframe, supprimer toutes les valeurs NA
et le répartir
en arrière
library(tidyverse) df %>% gather(key, value, - UserID) %>% na.omit() %>% spread(key, value) # UserID A B C #1 1 2018-09-20 18:00:55 2018-09-20 18:00:42 2018-09-20 18:00:38 #2 2 2018-09-2018:00:55 2018-09-20 18:00:55 2018-09-20 18:00:40 #3 4 2018-09-20 18:00:49 2018-09-20 18:00:49 <NA> #4 5 <NA> <NA> 2018-09-20 18:00:49
p >
Vous pouvez renseigner les valeurs connues dans les deux sens puis utiliser distinct sur le data.frame:
library(tidyverse) df %>% group_by(UserID) %>% fill(A:C) %>% fill(A:C, .direction = "up") %>% distinct() # A tibble: 4 x 4 # Groups: UserID [4] # UserID A B C # <dbl> <fct> <fct> <fct> # 1 1 2018-09-20 18:00:55 2018-09-20 18:00:42 2018-09-20 18:00:38 # 2 2 2018-09-2018:00:55 2018-09-20 18:00:55 2018-09-20 18:00:40 # 3 4 2018-09-20 18:00:49 2018-09-20 18:00:49 NA # 4 5 NA NA 2018-09-20 18:00:49
Nous pouvons utiliser melt / dcast
de data.table
library(tidyverse) df %>% gather(key, value, -UserID, na.rm = TRUE) %>% spread(key, value) # UserID A B C #1 1 2018-09-20 18:00:55 2018-09-20 18:00:42 2018-09-20 18:00:38 #2 2 2018-09-2018:00:55 2018-09-20 18:00:55 2018-09-20 18:00:40 #3 4 2018-09-20 18:00:49 2018-09-20 18:00:49 <NA> #4 5 <NA> <NA> 2018-09-20 18:00:49
De plus, collecte code > peut prendre
na.rm
comme argument. Ainsi, l'option similaire dans tidyverse
serait (en plus de l'approche de @Ronak Shah avec tidyverse
)
library(data.table) dcast(melt(setDT(df), id.var = 'UserID', na.rm = TRUE), UserID ~ variable) # UserID A B C #1: 1 2018-09-20 18:00:55 2018-09-20 18:00:42 2018-09-20 18:00:38 #2: 2 2018-09-2018:00:55 2018-09-20 18:00:55 2018-09-20 18:00:40 #3: 4 2018-09-20 18:00:49 2018-09-20 18:00:49 <NA> #4: 5 <NA> <NA> 2018-09-20 18:00:49
REMARQUE : L'approche tidyverse
n'est qu'une légère modification de la méthode de @ RonakShah. Il n'a été mentionné que pour montrer la similitude avec la solution principale ( melt / dcast
).
Les deux solutions fonctionnent, mais la solution melt / dcast fonctionne sans aucun avertissement. Dans le cas d'un avertissement tidyverse: «... les attributs ne sont pas identiques entre les variables de mesure; ils seront abandonnés ». Merci!
@Imitation Merci, l'avertissement est uniquement dû au fait que les colonnes A: C sont de la classe factor
et ont des niveaux différents. S'il s'agissait de caractère
, il n'y aurait pas d'avertissement. C'est juste un avertissement amical. Rien à craindre