web-dev-qa-db-fra.com

Une fonction pour remplir une colonne avec NA du même type

J'ai un cadre de données avec plusieurs colonnes de types différents. Je voudrais remplacer chaque colonne par NA de la classe correspondante.

par exemple:

df = data_frame(x = c(1,2,3), y = c("a", "b", "c"))

df[, 1:2] <- NA

donne une trame de données avec deux colonnes logiques plutôt que numérique et caractère ..__ Je sais que je peux dire à R:

df[,1] = as.numeric(NA)
df[,2] = as.character(NA)

Mais comment puis-je le faire collectivement dans une boucle pour toutes les colonnes avec tous les types possibles de NA?

17
Omry Atia

Vous pouvez utiliser ce "truc":

df[1:nrow(df),1] <- NA
df[1:nrow(df),2] <- NA

[1:nrow(df),] indique en gros à R de remplacer toutes les valeurs de la colonne avec NA. De cette manière, la logique NA est contrainte au type d'origine de la colonne avant de remplacer les autres valeurs.

De plus, si vous avez beaucoup de colonnes à remplacer et que le data_frame a beaucoup de lignes, je suggère de stocker les index de lignes et de les réutiliser:

rowIdxs <- 1:nrow(df)
df[rowIdxs ,1] <- NA
df[rowIdxs ,2] <- NA
df[rowIdxs ,3] <- NA
...

Comme suggéré intelligemment par @RonakShah , vous pouvez également utiliser: 

df[TRUE, 1] <- NA
df[TRUE, 2] <- NA
...

Comme indiqué par @Cath les deux méthodes fonctionnent toujours lorsque vous sélectionnez plusieurs colonnes, par exemple. :

df[TRUE, 1:3] <- NA
# or
df[1:nrow(df), 1:3] <- NA
10
digEmAll

Une autre solution applicable à all les colonnes peut être de spécifier les non-NA et de les remplacer par NA, c.-à-d.

df[!is.na(df)] <- NA

qui donne,

# A tibble: 3 x 2
      x    y    
  <dbl> <chr>
1    NA <NA> 
2    NA <NA> 
3    NA <NA> 
8
Sotos

Une autre façon de changer toutes les colonnes en même temps tout en conservant les classes des variables:

df[] <- lapply(df, function(x) {type <- class(x); x <- NA; class(x) <- type; x})

df
# A tibble: 3 x 2
#      x y    
#  <dbl> <chr>
#1    NA <NA> 
#2    NA <NA> 
#3    NA <NA> 

Comme @digEmAll a notifié dans les commentaires, il existe un autre moyen similaire mais plus court:

df[] <- lapply(df, function(x) as(NA,class(x)))
5
Cath

Utiliser dplyr :: na_if :

library(dplyr)

df %>% 
  mutate(x = na_if(x, x),
         y = na_if(y, y))

# # A tibble: 3 x 2
#       x y    
#   <dbl> <chr>
# 1    NA NA   
# 2    NA NA   
# 3    NA NA   

Si nous voulons muter uniquement un sous-ensemble de colonnes enNA, alors:

# dataframe with extra column that stay unchanged
df = data_frame(x = c(1,2,3), y = c("a", "b", "c"), z = c(4:6))

df %>% 
  mutate_at(vars(x, y), funs(na_if(.,.)))

# # A tibble: 3 x 3
#       x y         z
#   <dbl> <chr> <int>
# 1    NA NA        4
# 2    NA NA        5
# 3    NA NA        6
4
zx8754

En utilisant bind_cols() de dplyr, vous pouvez également effectuer les opérations suivantes:

df <- data_frame(x = c(1,2,3), y = c("a", "b", "c"))
classes <- sapply(df, class)
df[,1:2] <- NA

bind_cols(lapply(colnames(x), function(x){eval(parse(text=paste0("as.", classes[names(classes[x])], "(", df[,x],")")))}))

     V1 V2   
  <dbl> <chr>
1    NA NA   
2    NA NA   
3    NA NA 

S'il vous plaît noter que cela va changer les colnames.

0
alex_555