Я уверен, что, возможно, есть более элегантный способ сделать это, но посмотрите, дает ли это желаемый результат:
library(tidyverse)
data <- tribble(~ID, ~data,
"A", "[['education', 'Ph.D., MIT'], ['interests', 'Econometrics, Causal Inference']]",
"B", "[['function', 'Social']]",
"C", "[['research_interests', 'S&P']]",
"D", "[['field', 'American Politics']]")
column_names <- str_extract_all(data$data, "\\['(?<=').*?(?=')")
column_names <- map(column_names, ~ str_remove(.x, "\\['"))
names(column_names) <- data$ID
values <- str_extract_all(data$data, ",[:space:]'(?<=').*?(?=')")
values <- map(values, ~ str_remove(.x, ",[:space:]'"))
names(values) <- data$ID
val_df <- data.frame(values)%>%
gather("ID", "val")
col_df <- data.frame(column_names)%>%
gather("ID", "col")
bind_cols(col_df, val_df) %>%
distinct()%>%
spread(col, val, fill = NA)%>%
select(-ID1)
К сожалению, этот подход зависит как минимум от двух предположений:
- Имена столбцов всегда находятся в следующем формате "['column_name'"
- Значения всегда находятся в следующем формате ", 'value']"
Я не уверен, будет ли масштабироваться до остальной части ваших данных, но дайте мне знать, если это работает.
Изменить для добавления дополнительных критериев в комментариях
Если один идентификатор имеет две записи дляВ одном столбце у вас есть как минимум две опции:
- Создать вторую запись для идентификатора
paste
из двух значений в одно значение
Вот дополнительная примерная запись из комментариев (с моими правками «исследовательский интерес» к «исследовательский интерес с », при условии, что они должны совпадать с исходными данными):
"E", "[['research_interests', 'American Politics'], ['research_interests', 'Democratization']]"
Вариант 1: создать вторую запись
Это должно датьдве записи для 'E'
# Replace last step of the original answer with this:
two_records <- bind_cols(col_df, val_df) %>%
distinct()%>%
group_by(col)%>%
mutate(grouped_id = row_number()) %>%
spread(col, val, fill = NA)%>%
select(-ID1, -grouped_id)
Вариант 2. Вставьте два значения в 1
Это больше похоже на ваш исходный желаемый результат
# Replace last step of original answer with this:
paste_records <- bind_cols(col_df, val_df) %>%
distinct()%>%
group_by(col)%>%
mutate(grouped_id = row_number()) %>%
spread(col, val, fill = NA)%>%
select(-ID1, -grouped_id)
paste_records <- paste_records %>%
split(paste_records$ID)%>%
map_df(mutate_if, function(x)length(unique(x))>1, .funs = list(function(x)paste(x,collapse = ", ")))%>%
distinct()