Я пытаюсь обернуть голову вокруг замыканий, и я думаю Я нашел случай, когда они могут быть полезны.
У меня есть следующие части для работы:
- Набор регулярных выражений, предназначенных для очистки имен состояний, размещенных в функции
- data.frame с именами состояний (стандартизированной формы, которую создает вышеуказанная функция) и кодами идентификаторов состояний, чтобы связать их («карта слияния»)
Идея состоит в том, чтобы, учитывая некоторые data.frame с неаккуратными названиями штатов (прописная буква "Вашингтон, округ Колумбия", "Вашингтон, округ Колумбия", "Округ Колумбия" и т. Д.), Иметь одну функцию возврата тот же файл data.frame с удаленным столбцом имени состояния и оставшимися только кодами идентификаторов состояний. Тогда последующие слияния могут происходить последовательно.
Я могу сделать это любым количеством способов, но один из способов, который кажется особенно элегантным, состоит в размещении карты слияния, регулярного выражения и кода для обработки всего внутри замыкания (следуя идее, что замыкание является функция с данными).
Вопрос 1. Это разумная идея?
Вопрос 2: Если так, как мне это сделать в R?
Вот глупая простая функция очистки имен состояний, которая работает с данными примера:
cleanStateNames <- function(x) {
x <- tolower(x)
x[grepl("columbia",x)] <- "DC"
x
}
Вот некоторые примеры данных, на которых будет выполняться возможная функция:
dat <- structure(list(state = c("Alabama", "Alaska", "Arizona", "Arkansas",
"California", "Colorado", "Connecticut", "Delaware", "District of Columbia",
"Florida"), pop08 = structure(c(29L, 44L, 40L, 18L, 25L, 30L,
22L, 48L, 36L, 13L), .Label = c("1,050,788", "1,288,198", "1,315,809",
"1,316,456", "1,523,816", "1,783,432", "1,814,468", "1,984,356",
"10,003,422", "11,485,910", "12,448,279", "12,901,563", "18,328,340",
"19,490,297", "2,600,167", "2,736,424", "2,802,134", "2,855,390",
"2,938,618", "24,326,974", "3,002,555", "3,501,252", "3,642,361",
"3,790,060", "36,756,666", "4,269,245", "4,410,796", "4,479,800",
"4,661,900", "4,939,456", "5,220,393", "5,627,967", "5,633,597",
"5,911,605", "532,668", "591,833", "6,214,888", "6,376,792",
"6,497,967", "6,500,180", "6,549,224", "621,270", "641,481",
"686,293", "7,769,089", "8,682,661", "804,194", "873,092", "9,222,414",
"9,685,744", "967,440"), class = "factor")), .Names = c("state",
"pop08"), row.names = c(NA, 10L), class = "data.frame")
И пример карты слияния (фактическая карта связывает коды FIPS с состояниями, поэтому ее нельзя сгенерировать тривиально):
merge_map <- data.frame(state=dat$state, id=seq(10) )
РЕДАКТИРОВАТЬ Построение ответа Crippledlambda ниже, вот попытка функции:
prepForMerge <- local({
merge_map <- structure(list(state = c("alabama", "alaska", "arizona", "arkansas", "california", "colorado", "connecticut", "delaware", "DC", "florida" ), id = 1:10), .Names = c("state", "id"), row.names = c(NA, -10L ), class = "data.frame")
list(
replace_merge_map=function(new_merge_map) {
merge_map <<- new_merge_map
},
show_merge_map=function() {
merge_map
},
return_prepped_data.frame=function(dat) {
dat$state <- cleanStateNames(dat$state)
dat <- merge(dat,merge_map)
dat <- subset(dat,select=c(-state))
dat
}
)
})
> prepForMerge$return_prepped_data.frame(dat)
pop08 id
1 4,661,900 1
2 686,293 2
3 6,500,180 3
4 2,855,390 4
5 36,756,666 5
6 4,939,456 6
7 3,501,252 7
8 591,833 9
9 873,092 8
10 18,328,340 10
Осталось две проблемы, прежде чем я решу этот вопрос решенным:
Звонить prepForMerge$return_prepped_data.frame(dat)
каждый раз больно. Есть ли способ иметь функцию по умолчанию, чтобы я мог просто вызвать prepForMerge (dat)? Я догадываюсь, не учитывая, как это реализовано, но, возможно, есть по крайней мере соглашение для fxn по умолчанию ....
Как избежать смешивания данных и кода в определении merge_map? В идеале я бы очистил merge_map в другом месте, а затем просто взял бы его внутри замыкания и сохранил его.