Как это часто бывает, написание вопроса и минимального примера помогло мне упростить проблему и найти решение. Я уверен, что есть более причудливое решение, но это то, что я придумал, и легко (иш) разобраться.
Хотя форматы различаются, количество уникальных символов ограничено. В игрушечном примере в этой задаче только s, c, p, z
. Итак, вот что я сделал:
Сначала я создал функцию, которая принимает одну строку формата, одну строку геоида и один символ / код субгео. Функция определяет, какие позиции символов в format
соответствуют subgeo
, а затем возвращает эти позиции из geoid
.
extract_sub_geo <- function(format, geoid, subgeo) {
geoid_v <- unlist(strsplit(geoid, ""))
format_v <- unlist(strsplit(format, ""))
positions <- which(format_v == subgeo)
result <- paste(geoid_v[positions], collapse = "")
return(result)
}
extract_sub_geo("ssccczzzzzzzz", "0202000000126", "s")
[1] "02"
Затем я зациклился на каждом уникальном коде и использовал pmap()
, чтобы применить функцию ко всему фрейму данных.
geo_codes <- c("s", "c", "p", "z")
for (code in geo_codes) {
df <- df %>%
mutate(
!!code := pmap_chr(list(format, remainder, !!(code)), extract_sub_geo)
)
}
# A tibble: 2 x 6
geoid format s c p z
<chr> <chr> <chr> <chr> <chr> <chr>
1 0224230 ssppppp 02 "" 02000 ""
2 0202000000126 ssccczzzzzzzz 02 020 "" 00000126
Возможно, чище сделать цикл в базе R вместо dplyr.