3
votes

Remplacez les valeurs NA par 999 dans R sous-défini par ID

J'ai créé le dataframe suivant dans R

 Adding missing grouping variables: `ID`
 Error in tbl_if_vars(.tbl, .p, .env, ..., .include_group_vars = 
 .include_group_vars) : 
 length(.p) == length(tibble_vars) is not TRUE

Le dataframe généré est le suivant

   library(dplyr)
   df%>%
   group_by(ID)%>%
   select(II, JJ,KK)%>%
   mutate_if(df[, colSums(is.na(df)) == nrow(df)]<999)

Je souhaite sous-définir le dataframe par les valeurs d'ID et remplacez toutes les colonnes contenant uniquement des valeurs NA par 999. le résultat doit être comme suit

 ID  II  JJ KK
  A 999   1  1
  A 999   2  2
  A 999   3 NA
  B   1 999 NA
  B   2 999  5
  B   3 999  6

J'ai essayé ce code

  ID II JJ KK
   A NA  1  1
   A NA  2  2
   A NA  3 NA
   B  1 NA NA
   B  2 NA  5
   B  3 NA  6


2 commentaires

Pas un double de la recommandation @tifu


Vous avez raison, supprimera la recommandation


3 Réponses :


8
votes

Nous pouvons utiliser tous pour capturer des groupes avec tous les AN. Puisque nous voulons remplacer les NA dans toutes les colonnes, alors nous pouvons utiliser mutate_all , où les funs (c'est-à-dire la fonction à appliquer à tous les colonnes) est un simple replace () des groupes où les valeurs de all () sont NA. Le remplacement est 999 .

# A tibble: 6 x 4
# Groups:   ID [2]
  ID       II    JJ    KK
  <fct> <dbl> <dbl> <dbl>
1 A       999     1     1
2 A       999     2     2
3 A       999     3    NA
4 B         1   999    NA
5 B         2   999     5
6 B         3   999     6

qui donne,

library(tidyverse)

df %>% 
 group_by(ID) %>% 
 mutate_all(funs(replace(., all(is.na(.)), 999)))


2 commentaires

Soigné. Puis-je demander comment cela fonctionne monsieur. Je suis clair jusqu'à group_by mais de mutate_all je suis un peu flou


@marciaakshayaLeo J'ai ajouté une explication. Faites-moi savoir si vous avez d'autres questions



2
votes

Pour intégrer également une solution data.table :

library(data.table)
setDT(df)
df[, lapply(.SD, 
            function(col) if (all(is.na(col))) 999 else col), 
     by = ID]
#    ID  II  JJ KK
# 1:  A 999   1  1
# 2:  A 999   2  2
# 3:  A 999   3 NA
# 4:  B   1 999 NA
# 5:  B   2 999  5
# 6:  B   3 999  6

Nous parcourons toutes les colonnes non ID avec lapply et remplacez-les par 999 si tous sont NA.


2 commentaires

Vous pouvez utiliser setDT () au lieu de as.data.table () (c'est plus rapide) ET vous n'avez pas besoin de spécifier .SDcols --- il s'agit automatiquement de toutes les colonnes non spécifiées dans par .


Merci, j'apprends juste data.table (je suis plus un gars dplyr ) - je vais changer le code, merci pour votre perspicacité, très utile! +1



0
votes

Et une approche de base r:

df[sapply(df, function(x)
  if(is.numeric(x)) is.na(ave(x, df$ID, FUN = function(y)
    mean(y, na.rm = TRUE))) else rep(FALSE, length(x)))] <- 999

df
  ID  II  JJ KK
1  A 999   1  1
2  A 999   2  2
3  A 999   3 NA
4  B   1 999 NA
5  B   2 999  5
6  B   3 999  6


0 commentaires