2
votes

Rassembler des lignes non vides (format POSIXct) à partir de différentes colonnes pour le même UserID sur une seule ligne

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

Exemple de bloc de données

df2<-df %>% 
group_by(UserID) %>%
 filter(!is.na(A),  !is.na(B), !is.na(C))


0 commentaires

3 Réponses :


2
votes

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 >


0 commentaires

0
votes

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


0 commentaires

1
votes

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


2 commentaires

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