私はクロージャの周りを頭で囲んでいるのですが、私はと思っています。私は彼らが役に立つかもしれないケースを見つけました。データマージ慣用の解決策としてのクロージャ
私はで動作するように、次の部分があります。
- 状態名と機能
- data.frameに収納された状態名をきれいにするために設計された正規表現のセット、(標準化された形式のものを(上記の関数は作成されます)と状態IDコードは、2つをリンクするために( "マージマップ")
考えて、いくつかのdata.frameは、 "、"ワシントンDC "、"コロンビア特別区 "など)、罪を犯すgle関数は、状態名列が削除され、状態IDコードのみが残っている同じdata.frameを返します。その後、その後のマージは一貫して発生する可能性があります。
私はこれをいくつでも行うことができますが、特に優雅に思える方法の1つは、マージマップと正規表現とコード処理のすべてをクロージャ内に格納することです(クロージャがデータ付き関数)。
質問1:これは合理的な考えですか?
質問2:そうであれば、どのようにRで行うのですか?ここで
は、例えば、データ上で動作愚かな簡単なきれいな状態名機能です:
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")
とサンプルマージ:
cleanStateNames <- function(x) {
x <- tolower(x)
x[grepl("columbia",x)] <- "DC"
x
}
ここではいくつかの例のデータは、最終的な機能は、上で実行されることですmap(実際のものはFIPSコードを状態にリンクするので、簡単に生成することはできません):
merge_map <- data.frame(state=dat$state, id=seq(10))
EDIT以下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
2つの問題が残っている:prepForMerge$return_prepped_data.frame(dat)
を呼び出す
は痛い毎回です。どのように私はちょうどprepForMerge(dat)を呼び出すことができるようなデフォルトの機能を持っている?私はそれがどのように実装されているかはわかりませんが、おそらくデフォルトfxnのための規約があります。
merge_map定義にデータとコードを混ぜて使用しないでください。理想的には、別の場所でmerge_mapをクリーンアップしてから、クロージャーの中に入れて保存してください。
これは私にクロージャを使用する自然な場所のようではありません。 – hadley
@hadleyこれは質問1の範囲内であるため、答えとして投稿することはできますか?おそらく、これをクロージャの理想的な状況よりも少なくするようなことについての精緻化が必要です(実際にデータを更新する必要はありませんか? ?私はクロージャの「方法」については大丈夫ですが、「なぜ/いつ」の部分を使用するのに苦労しています。 –