«Текст в столбцы» поле в R с использованием различных переменных - PullRequest
1 голос
/ 29 января 2020

Я пытаюсь разграничить список в R, используя несколько разных значений, и мне кажется, что я сильно усложняю то, что мне нужно сделать.

Я бы хотел выделить что-нибудь в «положительный» список (ie., который начинает список или имеет знак + перед ним) в столбце «Позитив».

Все, что имеет знак «-» в столбце «Отрицательный».

Все, что похоже на c («EmilyP», «EmilyS») в столбец «Эмили»

, и все, что равно c («Красный», «Синий») в столбец «Цвет».

Я пробовал dplyr и tidyr и не могу выполнить эту работу, затем я начал работать над al oop, и это кажется слишком сложным.

Кто-нибудь может предложить лучший метод?

(входы и выходы ниже).

input <- structure(list(Team.Name = c("Team 1", "Team 2", "Team 3", "Team 4", 
"Team 5", "Team 6"), Members = c("Frank + Terry - Joan - Bob + EmilyS + Red", 
"Frank + Bob - Neil - Janet - Tim + EmilyP + Blue", "Frank + Blue - Joan - Bob + EmilyP + Red", 
"Tom + Jerry - Bill - Jenny", "Tess + Jean + Jill + EmilyS", 
"Bill + Bob + Red")), class = "data.frame", row.names = c(NA, 
-6L))

и я пытаюсь получить это:

output <- structure(list(Team.Name = c("Team 1", "Team 2", "Team 3", "Team 4", 
"Team 5", "Team 6"), Positive = c("Frank + Terry", "Frank + Bob", 
"Frank", "Tom + Jerry", "Tess + Jean + Jill", "Bill + Bob"), 
    Negative = c("Joan - Bob", "Neil - Janet - Tim", "Joan - Bob", 
    "Bill - Jenny", "", ""), Emily = c("EmilyS", "EmilyP", "EmilyP", 
    "", "EmilyS", ""), Color = c("Red", "Blue", "Red + Blue", 
    "", "", "Red")), class = "data.frame", row.names = c(NA, 
-6L))

1 Ответ

0 голосов
/ 29 января 2020

Это то, что я получил сейчас. Сначала я разделил участников и создал фрейм данных с map_dfr(). Затем я работал над некоторыми операциями со строками. Первый участник в каждой группе не имеет +. Я добавил это к первому участнику. Я заменил + или - до Emily, за которым следует заглавная буква Emily. Я также заменил + или - перед именем цвета на color. Затем я отделил столбец value с separate(). Для каждой группы я объединил все имена с toString(). Наконец, я преобразовал данные в широкоформатные данные.

library(tidyverse)
library(stringi)

map_dfr(.x = stri_split_regex(str = input$Members, pattern = "\\s(?=[+|-])"),
        .f = enframe,
        .id = "id") %>% 
mutate(value = if_else(!substr(x = value, start = 1, stop =1) %in% c("+", "-"),
                       paste("+ ", value, sep = ""), value),
       value = if_else(grepl(x = value, pattern = "Emily[A-Z]"),
                             sub(x = value, pattern = "[+|-]", replacement = "Emily"),
                             value),
       value = if_else(sub(x = value, pattern = "[+|-]\\s", replacement = "") %in% stri_trans_totitle(colors(distinct = TRUE)),
                       sub(x = value, pattern = "[+|-]", replacement = "color"),
                       value)) %>%
separate(col = "value", into = c("type", "value"), sep = "\\s") %>% 
group_by(id, type) %>%  
summarise(value = toString(value)) %>% 
pivot_wider(id_cols = "id", names_from = "type", values_from = "value")

#  id    `-`              `+`              color     Emily 
#  <chr> <chr>            <chr>            <chr>     <chr> 
#1 1     Joan, Bob        Frank, Terry     Red       EmilyS
#2 2     Neil, Janet, Tim Frank, Bob       Blue      EmilyP
#3 3     Joan, Bob        Frank            Blue, Red EmilyP
#4 4     Bill, Jenny      Tom, Jerry       NA        NA    
#5 5     NA               Tess, Jean, Jill NA        EmilyS
#6 6     NA               Bill, Bob        Red       NA    
...