Кто-нибудь знает о методе в R для объединения n столбцов, но сохранения разделителя только в том случае, если в этой строке есть значение? Если вы запустите приведенный ниже пример:
df <- data.frame(
name1 = c("Jim","Bob","Sue"),
name2 = c("Jane","","Bane"),
name3 = c('Conor',"",""),
name4 = c("","","Bonor")
)
df$names <- paste(df$name1,df$name2,df$name3, sep = ";")
Вы увидите, что разделители включены в конце и между значениями, даже если ячейки пусты, с выводом:
df =
name1 name2 name3 name4 names
Jim Jane Conor Jim;Jane;Conor;
Bob Bob;;;
Sue Bane Bonor Sue;Bane;;Bonor
Есть ли способ не включать или отбрасывать разделители в случае, когда ячейки пусты? С желаемым результатом:
df =
name1 name2 name3 name4 names
Jim Jane Conor Jim;Jane;Conor
Bob Bob
Sue Bane Bonor Sue;Bane;Bonor
library(dplyr)
library(tidyr)
df %>%
mutate_all(na_if,"") %>%
unite("names", everything(), sep = ";", remove = F, na.rm = T)
#> names name1 name2 name3 name4
#> 1 Jim;Jane;Conor Jim Jane Conor <NA>
#> 2 Bob Bob <NA> <NA> <NA>
#> 3 Sue;Bane;Bonor Sue Bane <NA> Bonor
Я изменяю ответ akrun из комментария ниже;
df %>%
mutate(across(c("name1", "name2", "name3", "name4"), na_if, "",
.names = "{.col}_changed")) %>%
unite(names, ends_with('_changed'), na.rm = TRUE, sep = ";")
#> name1 name2 name3 name4 names
#> 1 Jim Jane Conor Jim;Jane;Conor
#> 2 Bob Bob
#> 3 Sue Bane Bonor Sue;Bane;Bonor
Они оба великолепны, спасибо! Могу я спросить, в чем разница?
Ответ @JohnConor akrun не изменяет (заменяя пустые ячейки на NA) исходные столбцы, поскольку мы изменяем «вспомогательные» столбцы. Он также сохраняет порядок, который вы указали в желаемом выводе (сначала идет имя от имени 1 до имени 4, а объединенный столбец находится в конце).
Спасибо @M--! Еще одна вещь, которую я понял, заключается в том, что в моем реальном наборе данных мне действительно нужно передать имена или, по крайней мере, положение столбцов, поскольку в нем ~ 200 столбцов, и мне нужно только соединить 5 из них. Есть ли простой способ изменить метод для этого? Я могу обновить исходный вопрос, если это поможет.
Если вы не хотите менять исходные значения
df %>% mutate(across(starts_with('name'), na_if, "", .names = "{.col}_changed")) %>% unite(names, ends_with('changed'), na.rm = TRUE, sep = ";")