Как объединить несколько столбцов с разделителями, но игнорировать некоторые из столбцов на основе условия в R? - PullRequest
1 голос
/ 21 февраля 2020

Привет, я хотел бы объединить столбцы, содержащие строки или пробелы или NA с ";". Итак, давайте рассмотрим пример ниже:


Actor1<- c("Driver","NA","","")
Actor2<- c("President","Zombie","","")
Actor3<- c("CEO","Devil","","")
Actor4<-c("Priest","","Killer","Mayor")

df_ex <-data.frame(Actor1, Actor2, Actor3, Actor4)

я пробовал это:

df_ex %>%
  mutate(combined= paste0(Actor1,";",Actor2,";",Actor3,";",Actor4)) 

, но, очевидно, результат неправильный, например:

df_ex[3,]

результат в комбинированном столбце это: ;;; Killer

Я ожидаю, что результатом будет: Killer.

Примечание: есть также NA и пробелы "", которые также любят игнорировать.

заранее спасибо, ура

Ответы [ 3 ]

1 голос
/ 21 февраля 2020

Я далек от того, чтобы быть экспертом, но я поставлю здесь подход :

Actor1 <- c("Driver","NA","","")
Actor2 <- c("President","Zombie","","")
Actor3 <- c("CEO","Devil","","")
Actor4 <-c("Priest","","Killer","Mayor")

library(tidyverse)

data.frame(Actor1, Actor2, Actor3, Actor4) %>%
  mutate_all(~str_replace(., pattern = "NA", replacement = "")) %>% 
  unite(col = "combined", sep = ";", remove = F) %>% 
  mutate(combined = str_replace_all(combined, pattern = "^[:punct:]|[:punct:]$|[:punct:]{2,}", replacement = "")) %>% 
  select(-combined, everything(.), combined)

#>   Actor1    Actor2 Actor3 Actor4                    combined
#> 1 Driver President    CEO Priest Driver;President;CEO;Priest
#> 2           Zombie  Devil                       Zombie;Devil
#> 3                         Killer                      Killer
#> 4                          Mayor                       Mayor

Если вы хотите просто немного из столбцов, вы можете передать их в unite:

data.frame(Actor1, Actor2, Actor3, Actor4) %>%
  mutate_all(~str_replace(., pattern = "NA", replacement = "")) %>% 
  unite(Actor2, Actor4, col = "combined", sep = ";", remove = F) %>% 
  mutate(combined = str_replace_all(combined, pattern = "^[:punct:]|[:punct:]$|[:punct:]{2,}", replacement = "")) %>% 
  select(-combined, everything(.), combined)

#>   Actor1    Actor2 Actor3 Actor4         combined
#> 1 Driver President    CEO Priest President;Priest
#> 2           Zombie  Devil                  Zombie
#> 3                         Killer           Killer
#> 4                          Mayor            Mayor
1 голос
/ 21 февраля 2020
Actor1<- c("Driver","NA","","")
Actor2<- c("President","Zombie","","")
Actor3<- c("CEO","Devil","","")
Actor4<-c("Priest","","Killer","Mayor")

matrix_ex <-cbind(Actor1, Actor2, Actor3, Actor4)
#apply(df_ex,1,paste,collapse=";")
x<-apply(matrix_ex,1,function(x){paste(x[!(is.na(x)|x==""|x=="NA")],collapse=";")})
x

[1] "Driver;President;CEO;Priest" "Zombie;Devil"                "Killer"                      "Mayor"                                    
> cat(paste(x,collapse="\n"))
#Driver;President;CEO;Priest
#Zombie;Devil
#Killer
#Mayor



Чтобы ответить на комментарии:


df_ex <-data.frame(Actor1=Actor1, Actor2=Actor2, Actor3=Actor3, Actor4=Actor4,rnorm(4))

df_ex$concat<-apply(df_ex[c("Actor1","Actor3")],1,function(x){paste(x[!(is.na(x)|x==""|x=="NA")],collapse=";")})
df_ex$concat

df_ex$concat2<-apply(df_ex[c(1,3)],1,function(x){paste(x[!(is.na(x)|x==""|x=="NA")],collapse=";")})
df_ex$concat2
0 голосов
/ 21 февраля 2020

Вы можете попробовать приведенный ниже код, используя do.call + paste

df_ex$combine <- gsub("\\bNA;?\\b|;{2,}|;$","",do.call(paste,c(df_ex,sep = ";")))

, такой что

> df_ex
  Actor1    Actor2 Actor3 Actor4                     combine
1 Driver President    CEO Priest Driver;President;CEO;Priest
2     NA    Zombie  Devil                       Zombie;Devil
3                         Killer                      Killer
4                          Mayor                       Mayor
...