В примечании в конце мы показываем используемые здесь входные данные. Это как в вопросе, за исключением того, что мы добавили строку NA в конце, чтобы показать, что все решения работают и в этом случае.
Мы показываем решения как для списка, так и для символьного столбца. Вопрос конкретно относится к списку, поэтому это предполагаемый желаемый результат, но если предполагалось, что newCol
будет вектором символов, то мы также покажем это.
Это настолько легко сделать с помощью базовых функций, что мы сначала покажем это; тем не менее, мы повторяем это в tidyverse, хотя для этого требуется значительно больше кода.
1) base Мы можем использовать apply
следующим образом:
reduce <- function(x) unname(x[!is.na(x)])
DF$newCol <- apply(DF, 1, reduce)
давая следующее, где newCol
— это список, первым компонентом которого является c("dog", "cat")
и т. д.
col1 col2 col3 col4 newCol
1 dog cat <NA> <NA> dog, cat
2 <NA> cat foo bar cat, foo, bar
3 dog <NA> <NA> <NA> dog
4 <NA> cat <NA> <NA> cat
5 <NA> <NA> <NA> <NA>
Последняя строка кода поочередно может быть:
DF$newCol <- lapply(split(DF, 1:nrow(DF)), reduce)
Вопрос относится к объединению в список, поэтому я предполагаю, что список требуется для newCol
, но если требуется строка, вместо этого используйте это для уменьшения:
reduce_ch <- function(x) sprintf("(%s)", toString(x[!is.na(x)]))
apply(DF, 1, reduce_ch)
2) tidyverse или с помощью tpldyr/tidyr/tibble мы собираем его в длинную форму, удаляем NA, вкладываем, сортируем обратно в исходный порядок и связываем обратно с помощью DF
.
library(dplyr)
library(tibble)
library(tidyr)
DF %>%
rownames_to_column %>%
gather(colName, Value, -rowname) %>%
na.omit %>%
select(-colName) %>%
nest(Value, .key = newCol) %>%
arrange(rowname) %>%
left_join(cbind(DF %>% rownames_to_column), .) %>%
select(-rowname)
давая:
col1 col2 col3 col4 newCol
1 dog cat <NA> <NA> dog, cat
2 <NA> cat foo bar cat, foo, bar
3 dog <NA> <NA> <NA> dog
4 <NA> cat <NA> <NA> cat
5 <NA> <NA> <NA> <NA> NULL
Если требуется вывод символов, используйте это вместо этого:
DF %>%
rownames_to_column %>%
gather(colName, Value, -rowname) %>%
select(-colName) %>%
group_by(rowname) %>%
summarize(newCol = sprintf("(%s)", toString(na.omit(Value)))) %>%
ungroup %>%
{ cbind(DF, .) } %>%
select(-rowname)
давая:
col1 col2 col3 col4 newCol
1 dog cat <NA> <NA> (dog, cat)
2 <NA> cat foo bar (cat, foo, bar)
3 dog <NA> <NA> <NA> (dog)
4 <NA> cat <NA> <NA> (cat)
5 <NA> <NA> <NA> <NA> ()
Примечание
Вход DF
в воспроизводимой форме:
Lines <- "col1 col2 col3 col4
dog cat NA NA
NA cat foo bar
dog NA NA NA
NA cat NA NA
NA NA NA NA"
DF <- read.table(text = Lines, header = TRUE, as.is = TRUE)
person
G. Grothendieck
schedule
29.12.2017