Замыкания как решение идиомы слияния данных

Я пытаюсь осмыслить замыкания, и я думаю Я нашел случай где они могут быть полезны.

Мне нужно поработать со следующими частями:

  • Набор регулярных выражений, предназначенных для очистки имен состояний, размещенных в функции
  • 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) )

РЕДАКТИРОВАТЬ Создание Ниже приведен ответ с нарушением лямбды, вот попытка использования функции:

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

Прежде чем я буду считать этот вопрос решенным, остаются две проблемы:

  1. Вызов prepareForMerge $ return_prepped_data.frame (dat) каждый раз болезненно. Есть ли способ иметь функцию по умолчанию, чтобы я мог просто вызвать препФорМерже (дат)? Я предполагаю, что не знаю, как это реализовано, но, возможно, есть по крайней мере соглашение для fxn по умолчанию ....

  2. Как мне избежать смешивания данных и кода в определении merge_map? В идеале я бы очистил merge_map в другом месте, а затем просто взял бы его внутри закрытия и сохранил.

6
задан Ari B. Friedman 18 October 2011 в 04:23
поделиться