[英]functional programming problems -- map_df & regex
我正在嘗試使用函數式編程方法組合多個電子表格(大約 20 個)。 每個電子表格都包含一個單獨的年份數據。 它們很混亂,列未命名或同一列的名稱在電子表格中發生變化。
我最初為每個電子表格單獨進行了所有清理,但想學習如何使用函數式編程來完成它以使其更具可重復性。
我的方法是構建一個正則表達式來匹配指定列的所有不同名稱,然后使用自定義函數/正則表達式重命名該列。 我想我可以使用map_dfr
將此 function 應用於所有不同的電子表格,以生成最終的 dataframe 以使用。
但是我遇到了2個問題:
R 中的正則表達式引擎似乎打開了全局參數,無法將其關閉。 我想按順序匹配正則表達式中的不同可能性,並在找到第一個匹配項時停止,而不是所有匹配項。 例如,在我導入電子表格后,有時會有多個未命名的列獲得給定的名稱...1
等。我只想匹配第一個實例。 我似乎無法確定是否可以禁用全局參數,或者編寫正則表達式以在第一次匹配后停止的更聰明的方法。 還有另一種可能更好的方法來解決這個問題嗎?
當我通過我的自定義 function(它似乎在單個數據幀上運行良好)時,我從map_df
收到一個錯誤,我不太清楚為什么。
我在下面制作了一個最小的reprex,我認為它突出了這些問題。
所有的想法都受到了極大的歡迎,包括對此的替代方法,因為這一定是人們遇到的一個非常普遍的問題。 謝謝。
library(tidyverse)
year_1 <- tribble(
~`...1`, ~admissions,
"Hospital 1", 10,
"Hospital 2", 100,
"hospital 3", 200
)
year_2 <- tribble(
~provider_code, ~`...2`, ~admissions,
"H1", "Hospital 1", 20,
"H2", "Hospital 2", 400,
"H3", "hospital 3", 500
)
year_3 <- tribble(
~"Hospital provider code", ~"Commissioning region/Provider", ~admissions,
"H1", "Hospital 1", 350,
"H2", "Hospital 2", 350,
"H3", "hospital 3", 550
)
clean_up_area_column_name <- function(x){
rename({{x}}, area = matches("\\.{3}[0-9]|commissioning region|hospital provider", ignore.case = TRUE))
}
clean_up_area_column_name(year_1)
#> # A tibble: 3 × 2
#> area admissions
#> <chr> <dbl>
#> 1 Hospital 1 10
#> 2 Hospital 2 100
#> 3 hospital 3 200
clean_up_area_column_name(year_2)
#> # A tibble: 3 × 3
#> provider_code area admissions
#> <chr> <chr> <dbl>
#> 1 H1 Hospital 1 20
#> 2 H2 Hospital 2 400
#> 3 H3 hospital 3 500
clean_up_area_column_name(year_3)
#> # A tibble: 3 × 3
#> area1 area2 admissions
#> <chr> <chr> <dbl>
#> 1 H1 Hospital 1 350
#> 2 H2 Hospital 2 350
#> 3 H3 hospital 3 550
test_df <- map_dfr(c(year_1, year_2, year_3), clean_up_area_column_name)
#> Error in UseMethod("rename"): no applicable method for 'rename' applied to an object of class "character"
由reprex package (v2.0.1) 於 2022 年 8 月 8 日創建
將多個 data.frames 傳遞給map
需要一個list
test_df <- map_dfr(list(year_1, year_2, year_3), clean_up_area_column_name)
# A tibble: 9 x 5
area admissions provider_code area1 area2
<chr> <dbl> <chr> <chr> <chr>
1 Hospital 1 10 NA NA NA
2 Hospital 2 100 NA NA NA
3 hospital 3 200 NA NA NA
4 Hospital 1 20 H1 NA NA
5 Hospital 2 400 H2 NA NA
6 hospital 3 500 H3 NA NA
7 NA 350 NA H1 Hospital 1
8 NA 350 NA H2 Hospital 2
9 NA 550 NA H3 hospital 3
如您所說,如果您只想獲取第一個實例,那么對您的 function 進行以下調整應該可以工作。 將任何“area1”重命名為“area”,然后取消選擇帶有尾隨數字的剩余“area”列名稱(area2、area3 等)。
clean_up_area_column_name <- function(x){
rename({{x}},
area = matches("\\.{3}[0-9]|commissioning region|hospital provider")) %>%
rename(., area = matches("area1")) %>%
select(-any_of(matches("area\\d")))
}
我不確定您期望 year_3 返回什么,因為您的正則表達式似乎與provider_code
和area
匹配:
map_dfr(list(year_1, year_2, year_3), clean_up_area_column_name)
# A tibble: 9 × 3
area admissions provider_code
<chr> <dbl> <chr>
1 Hospital 1 10 NA
2 Hospital 2 100 NA
3 hospital 3 200 NA
4 Hospital 1 20 H1
5 Hospital 2 400 H2
6 hospital 3 500 H3
7 H1 350 NA
8 H2 350 NA
9 H3 550 NA
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.