2011-01-11 2 views
3

J'ai deux listes (d'une enquête multi-ondes) qui ressemblent à ceci:Combinant des articles d'enquête dans R/recodification NAs

X1 X2 
1 NA 
NA 2 
NA NA 

Comment puis-je combiner facilement en faire un troisième élément, où la troisième colonne prend toujours la valeur non-NA de la colonne X1 ou X2, et les codes NA lorsque les deux valeurs sont NA?

Répondre

5

En combinant l'utilisation de Gavin de within et l'utilisation de Prasad ifelse nous donne une réponse plus simple.

within(df, x3 <- ifelse(is.na(x1), x2, x1)) 

multiples ifelse appels ne sont pas nécessaires - lorsque les deux valeurs sont NA, vous pouvez simplement prendre l'une des valeurs directement.

+0

+1 bon point @Richie –

+0

1 - bien repéré. Belle simplification. –

2

Cela a besoin d'un peu de finesse-tion supplémentaire en raison de la possibilité à la fois X1 et X2 étant NA, mais cette fonction peut être utilisée pour résoudre votre problème:

foo <- function(x) { 
    if(all(nas <- is.na(x))) { 
     NA 
    } else { 
     x[!nas] 
    } 
} 

Nous utilisons la fonction foo en l'appliquant à chaque ligne de vos données (ici je vos données dans un objet nommé dat):

> apply(dat, 1, foo) 
[1] 1 2 NA 

cela nous donne ce que nous voulons. Pour inclure cela à l'intérieur de votre objet, nous le faisons:

> dat <- within(dat, X3 <- apply(dat, 1, foo)) 
> dat 
    X1 X2 X3 
1 1 NA 1 
2 NA 2 2 
3 NA NA NA 
3

Une autre façon en utilisant ifelse:

df <- data.frame(x1 = c(1, NA, NA, 3), x2 = c(NA, 2, NA, 4)) 
> df 
    x1 x2 
1 1 NA 
2 NA 2 
3 NA NA 
4 3 4 

> transform(df, x3 = ifelse(is.na(x1), ifelse(is.na(x2), NA, x2), x1)) 
    x1 x2 x3 
1 1 NA 1 
2 NA 2 2 
3 NA NA NA 
4 3 4 3 
0

Vous ne dites pas ce que vous vouliez faire quand les deux étaient des nombres valides, mais vous pouvez utiliser pmax ou pMin avec l'argument na.rm:

pmax(df$x1, df$x2, na.rm=TRUE) 
# [1] 1 2 NA 4