2014-09-10 91 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