R语言 如果元素不同,则折叠

zbsbpyhn  于 2022-12-06  发布在  其他
关注(0)|答案(4)|浏览(202)

我有两个列,如果它们不相同,我想将它们折叠。如果它们相同,则保留值。如果有一个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

有什么提示吗?
数据来源:

df = data.frame(element1 = c("A", "B",  "C","A"),
                 element2 = c("", "B","D", NA));df
eaf3rand

eaf3rand1#

请尝试使用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)),
                                              collapse = ','),whitespace = ',')) %>%
  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
trnvg8h3

trnvg8h32#

这是否有效:

> 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
>
2vuwiymt

2vuwiymt3#

下面是另一个tidyverse选项。
如果你想去掉令人讨厌的空字符串"",把它们变成NA,你可以使用na_if
如果字符串不同,case_when可以将它们连接起来,如果缺少其中一个字符串,则使用coalesceNA)。
如果两者都不是这种情况,则两列相同,并且仅设置为第一个值。

library(tidyverse)

df %>%
  na_if("") %>%
  mutate(element12 = case_when(
    element1 != element2 ~ paste(element1, element2, sep = ','),
    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
p1tboqfb

p1tboqfb4#

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"

相关问题