2014-09-10 51 views
0

如果一列中的元素不是NA,我希望paste0兩列。如果一列中的一個元素
NA,那麼只保留另一列的元素。R paste0 2列如果不是NA

structure(list(col1 = structure(1:3, .Label = c("A", "B", "C"), 
      class = "factor"), col2 = c(1, NA, 3)), .Names = c("col1", "col2"), 
      class = "data.frame",row.names = c(NA, -3L)) 

# col1 col2 
# 1 A 1 
# 2 B NA 
# 3 C 3 

structure(list(col1 = structure(1:3, .Label = c("A", "B", "C"), 
      class = "factor"),col2 = c(1, NA, 3), col3 = c("A|1", "B", "C|3")), 
     .Names = c("col1", "col2", "col3"), row.names = c(NA,-3L), 
      class = "data.frame") 

# col1 col2 col3 
#1 A 1 A|1 
#2 B NA B 
#3 C 3 C|3 
+0

你在哪裏卡住了?這應該很容易使用'ifelse'。 – Roland 2014-09-10 14:05:58

+0

你說你想使用'paste0',但你的例子看起來像'paste'的結果... – 2014-09-10 14:13:19

+0

@BenBolker這是我的錯字。我的意思是過去0。將糾正它。有沒有辦法執行這個任務沒有ifelse? – DJJ 2014-09-10 14:15:15

回答

1

由於@Roland說,這是很容易使用ifelse(只是翻譯的心理邏輯爲一系列嵌套ifelse語句):

x <- transform(x,col3=ifelse(is.na(col1),as.character(col2), 
        ifelse(is.na(col2),as.character(col1), 
          paste0(col1,"|",col2)))) 

更新:需要as.character在某些情況下。

+0

我嘗試了你的方法,並在第3列中獲得了2而不是B,這是我想找到另一種方式的原因的一部分。 – DJJ 2014-09-10 14:45:00

1

嘗試:

> df$col1 = as.character(df$col1) 
> df$col3 = with(df, ifelse(is.na(col1),col2, ifelse(is.na(col2), col1, paste0(col1,'|',col2)))) 
> df 
    col1 col2 col3 
1 A 1 A|1 
2 B NA B 
3 C 3 C|3 
3

,您還可以使用正則表達式做到這一點:

df$col3 <- sub("NA\\||\\|NA", "", with(df, paste0(col1, "|", col2))) 

也就是說,將它們粘貼到正規的方式,然後更換任何 「NA |」或「| NA」與「」。請注意,|需要「雙重逃脫」,因爲它意味着「正則表達式」的OR,這就是爲什麼奇怪模式NA\\||\\|NA實際上意味着「NA |」 OR「| NA」。

1

你也可以這樣做:

library(stringr) 
    df$col3 <- apply(df, 1, function(x) 
       paste(str_trim(x[!is.na(x)]), collapse="|")) 
    df 
    # col1 col2 col3 
    #1 A 1 A|1 
    #2 B NA B 
    #3 C 3 C|3