Мутировать несколько столбцов в R в зависимости от условий - PullRequest
0 голосов
/ 12 декабря 2018

Возможно, это глупость, которую я делаю, но я пытаюсь объединить значения некоторых столбцов, основываясь на том, содержат ли они значение или нет, а затем создать два новых столбца с именами start.week и end.week.

Мой start.week - «понедельник, вторник и среда».End.week - «четверг и пятница».

 Name        Monday Tuesday Wednesday   Thursday    Friday
 John        Red            Pink        
 Francis     Blue   Gray                 Black  
 Bill        Green          Orange       Purple 
 Bob         Yellow                      Lilac      Magenta

Я могу добавить две колонки для четверга и пятницы, используя:

start.week = c("Monday", "Tuesday", "Wednesday")
end.week = c("Thursday", "Friday")

options(stringsAsFactors = FALSE)
df = mutate(df, end.week = ifelse(Friday != "", paste0(Thursday, " + ", Friday), Thursday))

Назад Я не могу понять, какк этому для start.week

Может кто-нибудь дать мне подсказку?Буду вечно благодарен.

Исходные данные:

df = structure(list(Name = c("John", "Francis", "Bill", "Bob"), Monday = 
c("Red", "Blue", "Green", "Yellow"), Tuesday = c("", "Gray", "", ""), 
Wednesday = c("Pink", "", "Orange", ""), Thursday = c("", 
"Black", "Purple", "Lilac"), Friday = c("", "", "", "Magenta"
)), class = "data.frame", row.names = c(NA, -4L))

Ожидаемый результат:

 df = structure(list(Name = c("John", "Francis", "Bill", "Bob"), Monday = 
 c("Red", "Blue", "Green", "Yellow"), Tuesday = c("", "Gray", "", ""), 
Wednesday = c("Pink", "", "Orange", ""), Thursday = c("", 
"Black", "Purple", "Lilac"), Friday = c("", "", "", "Magenta"
), start.week = c("Red + Pink", "Black", "Green + Orange", 
"Yellow"), end.week = c("", "", "Purple", "Lilac + Magenta"
)), class = "data.frame", row.names = c(NA, -4L))

1 Ответ

0 голосов
/ 12 декабря 2018

Как насчет этого?

library(tidyverse)
df %>%
    gather(key, val, -Name) %>%
    group_by(Name) %>%
    mutate(
        start.week = paste(val[key %in% start.week & val != ""], collapse = " + "),
        end.week = paste(val[key %in% end.week & val != ""], collapse = " + ")) %>%
    spread(key, val)
## A tibble: 4 x 8
## Groups:   Name [4]
#  Name    start.week     end.week      Friday Monday Thursday Tuesday Wednesday
#  <chr>   <chr>          <chr>         <chr>  <chr>  <chr>    <chr>   <chr>
#1 Bill    Green + Orange Purple        ""     Green  Purple   ""      Orange
#2 Bob     Yellow         Lilac + Mage… Magen… Yellow Lilac    ""      ""
#3 Francis Blue + Gray    Black         ""     Blue   Black    Gray    ""
#4 John    Red + Pink     ""            ""     Red    ""       ""      Pink

Идея состоит в том, чтобы преобразовать данные из широких в длинные, добавить новые столбцы start.week и end.week и затем преобразовать данные обратно в широкие.

Или мы можем использовать purrr::imap_dfc для некоторой автоматизации генерации новых столбцов;для этого нам нужно сохранить новые столбцы с именем list.

lst <- list(start.week = start.week, end.week = end.week)
df %>%
    gather(key, val, -Name) %>%
    group_by(Name) %>%
    mutate(
        tmp = list(imap_dfc(lst, ~paste(val[key %in% .x & val != ""], collapse = "+")))) %>%
    unnest() %>%
    spread(key, val)

Обратите внимание, что я думаю, что в вашем ожидаемом выводе есть ошибка;start.week для Francis должно быть Blue + Gray, а не Black.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...