如果元素不同,则折叠

问题描述

我有两列要折叠,如果它们不同。如果它们相同,则保留该值。如果有一个root@c5b4010d03be:/app# ./clean_architecture.WebUI ,请保留另一个

NA

我需要下面的列:

df
#   element1 element2
#1        A         
#2        B        B
#3        C        D
#4        A     <NA>

关于我该怎么做的任何提示

数据:

#  element1 element2 element12
#1        A                  A
#2        B        B         B
#3        C        D       C,D
#4        A     <NA>         A

解决方法

尝试使用apply()的这种方法:

#Code 1
df$Var <- apply(df[1:2],1,function(x) trimws(paste0(unique(x[!is.na(x)]),collapse = ','),whitespace = ','))

输出:

  element1 element2 Var
1        A            A
2        B        B   B
3        C        D C,D
4        A     <NA>   A

dplyr版本:

library(dplyr)
#Code
df %>% mutate(across(everything(),~as.character(.))) %>%
  replace(is.na(.),',') %>%
  rowwise() %>%
  mutate(Var=trimws(paste0(unique(c_across(element1:element2)),')) %>%
  replace(.==',NA)

输出:

# A tibble: 4 x 3
# Rowwise: 
  element1 element2 Var  
  <chr>    <chr>    <chr>
1 A        ""       A    
2 B        "B"      B    
3 C        "D"      C,D  
4 A         NA      A  
,

这项工作:

> df %>% mutate(element3 = case_when(
There were 14 warnings (use warnings() to see them)
+                                   element1 == element2 ~ element1,+                                   is.na(element1) & !is.na(element2) ~ element2,+                                   is.na(element2) & !is.na(element1) ~ element1,+                                   element1 == '' & element2 != '' ~ element2,+                                   element1 != '' & element2 == '' ~ element1,+                                   element1 != element2 ~ paste(element1,element2,sep = ',')
+ ))
  element1 element2 element3
1        A                 A
2        B        B        B
3        C        D      C,D
4        A     <NA>        A
> 
,

这是另一个tidyverse选项。

如果您想摆脱烦人的空字符串""并使其成为NA,则可以使用na_if

case_when可以连接字符串(如果它们不同),并使用coalesce来防止一个或另一个字符串丢失(NA)。

如果都不是,则两列都相同,只是设置为第一个值。

library(tidyverse)

df %>%
  na_if("") %>%
  mutate(element12 = case_when(
    element1 != element2 ~ paste(element1,is.na(element1) | is.na(element2) ~ coalesce(element1,element2),TRUE ~ element1))

输出

  element1 element2 element12
1        A     <NA>         A
2        B        B         B
3        C        D       C,D
4        A     <NA>         A
,

base R中,我们可以使用pastesub

df$elements12 <- gsub("(?<=.)(?=.)",",sub("(.)\\1+","\\1",do.call(paste,c(replace(df,is.na(df),""),sep=""))),perl = TRUE)

-输出

df$element12
#[1] "A"   "B"   "C,D" "A"