Разделить строку на основе определенной пунктуации - PullRequest
1 голос
/ 04 октября 2019

Рассмотрим приведенный ниже примерный фрейм данных;

Примерный фрейм данных

|                   outcome                              
| 
----------------------------------------------------------
| Stewart Young, CEO, ABC Corp; Mark Hill, CFO, DCB Corp |
| Hill Man, Executive, FC Bank                           
|

Я хотел бы выполнить разбиение строки на основе ;, а затем разбить на ,. Например, мне понадобится следующий результат:

|          Name           |   Role   |        Company     |
-----------------------------------------------------------
| Stewart Young, Mark Hill| CEO, CFO | ABC Corp, DCB Corp |
|          Hill Man       | Executive|  FC Bank           |

Я могу выполнить разбиение строки на ;, но не могу получить точные имена, роли и компанию.

Ответы [ 2 ]

3 голосов
/ 04 октября 2019

Вот базовое решение R, которое, кажется, работает:

output <- apply(df, 1, function(r) {
    parts <- unlist(strsplit(r, ";\\s*"))
    Name <- sapply(parts, function(x) { strsplit(x, ",\\s*")[[1]][1] })
    Name <- paste(Name, collapse=", ")
    Role <- sapply(parts, function(x) { strsplit(x, ",\\s*")[[1]][2] })
    Role <- paste(Role, collapse=", ")
    Company <- sapply(parts, function(x) { strsplit(x, ",\\s*")[[1]][3] })
    Company <- paste(Company, collapse=",")
    c(Name, Role, Company)
})
output <- data.frame(t(output))
output

                    X1        X2                X3
1 Stewart Young, Mark Hill  CEO, CFO ABC Corp,DCB Corp
2                 Hill Man Executive           FC Bank

Данные:

df <- data.frame(outcome=c("Stewart Young, CEO, ABC Corp; Mark Hill, CFO, DCB Corp",
    "Hill Man, Executive, FC Bank"),
    stringsAsFactors=FALSE)
2 голосов
/ 04 октября 2019

Я бы предложил хранить каждую запись в отдельном ряду, а не объединять их вместе. Использование dplyr и tidyr в одну сторону будет

library(dplyr)
library(tidyr)

df %>%
  separate_rows(outcome, sep = ";") %>%
  separate(outcome, c("Name", "Role", "Company"), sep = ", ")

#           Name       Role   Company
#1 Stewart Young        CEO  ABC Corp
#2     Mark Hill        CFO  DCB Corp
#3      Hill Man  Executive   FC Bank

Однако, если вам нужен вывод, как показано, мы можем сделать

df %>%
  mutate(row = row_number()) %>%
  separate_rows(outcome, sep = ";") %>%
  separate(outcome, c("Name", "Role", "Company"), sep = ", ") %>%
  group_by(row) %>%
  summarise_all(toString) %>%
  select(-row)

#  Name                      Role      Company           
#  <chr>                     <chr>     <chr>             
#1 Stewart Young,  Mark Hill CEO, CFO  ABC Corp, DCB Corp
#2 Hill Man                  Executive FC Bank         

data

df <- structure(list(outcome = structure(2:1, .Label = c("Hill Man,
Executive, FC Bank", "Stewart Young, CEO, ABC Corp; Mark Hill, CFO, DCB Corp"), 
class = "factor")), class = "data.frame", row.names = c(NA, -2L))       
...