2015-01-08 24 views
7

Mam ramki danych z dwóch kolumnach „a” i „b” na przemian brakujących wartości (NA)łączą dwie kolumny ciąg z naprzemiennych brakujących wartości jednego

a  b 
dog <NA> 
mouse <NA> 
<NA> cat 
bird <NA> 

chcę „scalić”/połączyć im nowej kolumnie c, który wygląda jak ten, czyli nie- NA element w każdym wierszu jest zaznaczone:

c 
dog 
mouse 
cat 
bird 

próbowałem merge i join, ale nie pracował jak chciałem. Może dlatego, że nie mam identyfikatora, z którym mogę się połączyć? Dla liczb całkowitych po prostu obejść to i dodać obie kolumny, ale jak w moim przypadku?

+0

Czy to prawdziwe 'wartości NA' lub fałszywe? –

Odpowiedz

8

Możesz spróbować pmax

df$c <- pmax(df$a, df$b) 
df 
#  a b  c 
# 1 dog <NA> dog 
# 2 mouse <NA> mouse 
# 3 <NA> cat cat 
# 4 bird <NA> bird 

... lub ifelse:

df$c <- ifelse(is.na(df$a), df$b, df$a)

Dla bardziej ogólnych rozwiązań w przypadkach więcej niż dwóch kolumn, można znaleźć kilka sposobów realizacji COALESCE w R here.

+0

najlepszym rozwiązaniem dla mnie była druga opcja z użyciem 'ifelse'. Dzięki –

4

Napisałem funkcję coalesce() dla tego typu zadań, która działa podobnie do funkcji koalescencji SQL. Można by użyć go jak

dd<-read.table(text="a  b 
dog NA 
mouse NA 
NA cat 
bird NA", header=T) 

dd$c <- with(dd, coalesce(a,b)) 
dd 
#  a b  c 
# 1 dog <NA> dog 
# 2 mouse <NA> mouse 
# 3 <NA> cat cat 
# 4 bird <NA> bird 
3

Oto moja próba (zmodyfikowany przez @MrFlick)

df$c <- apply(df, 1, function(x) na.omit(x)[1]) 
df 
#  a b  c 
# 1 dog <NA> dog 
# 2 mouse <NA> mouse 
# 3 <NA> cat cat 
# 4 bird <NA> bird 
+1

Nie ma zastosowania (df, 1, function (x) na.omit (x) [1]) "działa równie dobrze tutaj i być nieco prostsze? – MrFlick

+0

Tak, ładnie złapać ... –

+1

Chciałbym również użyć 'df [który (! Is.na (df), arr.ind = TRUE)]' – akrun

1

Można użyć prostego apply:

df$c <- apply(df,1,function(x) x[!is.na(x)] ) 

> df 
     a b  c 
1 dog <NA> dog 
2 mouse <NA> mouse 
3 <NA> cat cat 
4 bird <NA> bird 
2

Inną opcją jest użycie which z arr.ind=TRUE

indx <- which(!is.na(df), arr.ind=TRUE) 
df$c <- df[indx][order(indx[,1])] 
df 
# a b  c 
#1 dog <NA> dog 
#2 mouse <NA> mouse 
#3 <NA> cat cat 
#4 bird <NA> bird 

Or

df$c <- df[cbind(1:nrow(df),max.col(!is.na(df)))] 
Powiązane problemy