2016-06-06 23 views
0

Ich habe ein Dataset wie das generische Dataset unten und möchte die drei Site-Variablen in eins zu verbinden.Join drei Spalten Spalten in einem Datenrahmen

df <- data.frame(var1 = c("site1", NA, NA, NA, "site3", "site4"), 
        var2 = c(NA, NA, "NA", "site2", NA, "site4"), 
        var3 = c("site1", NA, "Site2", "site2", "site3", NA)) 

    var1 var2 var3 
1 site1 <NA> site1 
2 <NA> <NA> <NA> 
3 <NA> NA Site2 
4 <NA> site2 site2 
5 site3 <NA> site3 
6 site4 site4 <NA> 

Der Datenrahmen Ich möchte so erhalten, sollte wie folgt sein:

 var1 var2 var3 var4 
1 site1 <NA> site1 site1 
2 <NA> <NA> <NA> <NA> 
3 <NA> NA Site2 site2 
4 <NA> site2 site2 site2 
5 site3 <NA> site3 site3 
6 site4 site4 <NA> site4 

Ich habe versucht, in der sqldf Paket mit verschmelzen, die die korrekte Ausgabe gibt, aber str() zeigt, dass die Ausgabe ist ein Datenrahmen mit einer Variablen. und nicht eine Reihe von Faktoren, wie ich brauche.

library(sqldf) 
df$var4 <-sqldf("select coalesce(var1, var2, var3) from df") 
> df 
    var1 var2 var3 coalesce(var1, var2, var3) 
1 site1 <NA> site1      site1 
2 <NA> <NA> <NA>      <NA> 
3 <NA> NA Site2       NA 
4 <NA> site2 site2      site2 
5 site3 <NA> site3      site3 
6 site4 site4 <NA>      site4 
> str(df) 
'data.frame': 6 obs. of 4 variables: 
$ var1: Factor w/ 3 levels "site1","site3",..: 1 NA NA NA 2 3 
$ var2: Factor w/ 3 levels "NA","site2","site4": NA NA 1 2 NA 3 
$ var3: Factor w/ 4 levels "site1","site2",..: 1 NA 3 2 4 NA 
$ var4:'data.frame': 6 obs. of 1 variable: 
    ..$ coalesce(var1, var2, var3): chr "site1" NA "NA" "site2" ... 
Warning message: 
+0

Relevanter Beitrag: http://stackoverflow.com/questions/19253820/how-to-implement-coalesce-efficiently-in-r – zx8754

Antwort

1

Sie können cbind() verwenden, um die beiden Datenrahmen wie zu fusionieren:

tmp = sqldf("select coalesce(var1, var2, var3) from df") 
df = cbind(df, tmp) 

ändern Sie dann die colname von

colnames(df)[4] = 'var4' 
+0

Das funktionierte wie ein Zauber, warum habe ich das selbst nicht erkannt. Vielen Dank! – Thoegernh

1

Vielleicht könnte dies eine mögliche Lösung:

df<- data.frame(var1 = c("site1", NA, NA, NA, "site3", "site4"), 
       var2 = c(NA, NA, "NA", "site2", NA, "site4"), 
       var3 = c("site1", NA, "Site2", "site2", "site3", NA)) 

getLastNonNA <- function(v){ 
    notNAs <- !is.na(v) 
    if(!any(notNAs)) 
    return(NA) 
    tail(v[notNAs],1) 
} 

# if you prefer the first non-NA 
#getFirstNonNA <- function(v){ 
# notNAs <- !is.na(v) 
# if(!any(notNAs)) 
# return(NA) 
# head(v[notNAs],1) 
#} 

df$var4 <- apply(df,1,getLastNonNA) 

> df 
    var1 var2 var3 var4 
1 site1 <NA> site1 site1 
2 <NA> <NA> <NA> <NA> 
3 <NA> NA Site2 Site2 
4 <NA> site2 site2 site2 
5 site3 <NA> site3 site3 
6 site4 site4 <NA> site4 

Beachten Sie, dass die letzte Spalte ist ein Zeichenvektor, aber Sie können leicht in Faktor konvertieren, wenn Sie wollen (mit as.factor).

2

Sie können na.locf von zoo Paket verwenden var4 zu bekommen,

library(zoo) 
df$var4 <- na.locf(t(df))[ncol(df),] 
df 
# var1 var2 var3 var4 
#1 site1 <NA> site1 site1 
#2 <NA> <NA> <NA> <NA> 
#3 <NA> NA Site2 Site2 
#4 <NA> site2 site2 site2 
#5 site3 <NA> site3 site3 
#6 site4 site4 <NA> site4 
2

Eine andere Möglichkeit, so etwas zu verwenden ist:

df$var4 <- apply(df, 1, min, na.rm = TRUE) 

Die Ausgabe wird wie folgt dar:

var1 var2 var3 var4 
1 site1 <NA> site1 site1 
2 <NA> <NA> <NA> <NA> 
3 <NA> <NA> Site2 Site2 
4 <NA> site2 site2 site2 
5 site3 <NA> site3 site3 
6 site4 site4 <NA> site4 
+0

Eine andere Option ist 'do.call (pmin, c (lapply (df, as.zeichen), list (na.rm = TRUE)))' – akrun

1

Wir können max.col

verwenden 210
df$var4 <- df[cbind(1:nrow(df), max.col(!is.na(df), "first"))] 
df 
# var1 var2 var3 var4 
#1 site1 <NA> site1 site1 
#2 <NA> <NA> <NA> <NA> 
#3 <NA> <NA> Site2 Site2 
#4 <NA> site2 site2 site2 
#5 site3 <NA> site3 site3 
#6 site4 site4 <NA> site4 
Verwandte Themen