Я работаю с таблицей, которая выглядит так:
library(tidyverse)
id <- c(1, 1, 2, 2)
year <- rep(1990:1991, 2)
occ <- c("former farmer carpenter", "cleaner janitor", "carpenter", "carpenter former cleaner")
old_occ <- c("former farmer", "cleaner", "", "")
df <- tibble(id, year, occ, old_occ)
Я хотел бы разделить строки, чтобы всем заголовкам была дана отдельная ячейка, например:
id occ1 occ2
1 former farmer carpenter
1 cleaner janitor
2 carpenter
2 carpenter former cleaner
Это было бы довольно просто, если бы все ячейки содержали либо одну профессию, например «плотник», либо две профессии, например «уборщик дворник». Однако, как вы можете видеть, названия некоторых профессий содержат информацию о предыдущих профессиях, например, «бывший уборщик». Эти названия профессий состоят из двух строк и могут идти до или после текущей профессии в ячейке.
Есть ли у кого-нибудь предложение о том, как я могу разделить строки для достижения желаемого результата?
Что ж, вполне возможно, что профессий больше двух, но других префиксов, кроме «бывший», нет.
Обратите внимание, что я улучшил свой ответ с помощью sprintf
.
Как предложил @GKi в комментариях, вы можете использовать gsub
для объединения названий "former_*"
с "_"
с помощью регулярных выражений. Затем strsplit
и unique
ify, настроить length
s и cbind
.
df[] <- lapply(df, function(x) gsub("(?<=former)\\s", "_", x, perl=TRUE))
tmp <- lapply(strsplit(Reduce(paste, df[c("occ", "old_occ")]), " "), unique)
mxlen <- max(lengths(tmp))
res <- cbind(df[-(3:4)],
`colnames<-`(t(sapply(tmp, `length<-`, mxlen)),
paste0("title", sprintf(paste0(".%0", mxlen, "d"), seq(mxlen)))))
res
# id year title.01 title.02
# 1 1 1990 former_farmer carpenter
# 2 1 1991 cleaner janitor
# 3 2 1990 carpenter <NA>
# 4 2 1991 carpenter former_cleaner
Вы можете создать новую строку для каждого слова, объединить former
со значением следующего слова и получить данные в широком формате.
library(dplyr)
library(tidyr)
df %>%
mutate(row = row_number()) %>%
separate_rows(occ) %>%
group_by(id, row) %>%
group_by(grp = lag(cumsum(occ != 'former'), default = 0) + 1, .add = TRUE) %>%
summarise(occ = paste0(occ, collapse = ' ')) %>%
pivot_wider(names_from = grp, values_from = occ, names_prefix = 'occ') %>%
ungroup %>% select(-row)
# id occ1 occ2
# <dbl> <chr> <chr>
#1 1 former farmer carpenter
#2 1 cleaner janitor
#3 2 carpenter NA
#4 2 carpenter former cleaner
Может что-то вроде:
strsplit(gsub("former ", "former_", df$occ), " ")
?