问题描述
我有两列要折叠,如果它们不同。如果它们相同,则保留该值。如果有一个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
中,我们可以使用paste
和sub
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"