簡體   English   中英

函數式編程問題——map_df & regex

[英]functional programming problems -- map_df & regex

我正在嘗試使用函數式編程方法組合多個電子表格(大約 20 個)。 每個電子表格都包含一個單獨的年份數據。 它們很混亂,列未命名或同一列的名稱在電子表格中發生變化。

我最初為每個電子表格單獨進行了所有清理,但想學習如何使用函數式編程來完成它以使其更具可重復性。

我的方法是構建一個正則表達式來匹配指定列的所有不同名稱,然后使用自定義函數/正則表達式重命名該列。 我想我可以使用map_dfr將此 function 應用於所有不同的電子表格,以生成最終的 dataframe 以使用。

但是我遇到了2個問題:

  1. R 中的正則表達式引擎似乎打開了全局參數,無法將其關閉。 我想按順序匹配正則表達式中的不同可能性,並在找到第一個匹配項時停止,而不是所有匹配項。 例如,在我導入電子表格后,有時會有多個未命名的列獲得給定的名稱...1等。我只想匹配第一個實例。 我似乎無法確定是否可以禁用全局參數,或者編寫正則表達式以在第一次匹配后停止的更聰明的方法。 還有另一種可能更好的方法來解決這個問題嗎?

  2. 當我通過我的自定義 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_codearea匹配:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM