簡體   English   中英

訪問要在 dplyr::mutate 中使用的函數中的列名

[英]Access column names in a function to be used in dplyr::mutate

使用 OECD 數據,我可以檢索一個數據庫,其中變量由它們的 ID 和帶有相應標簽的列表指定。 這是一個重現數據結構的最小示例:

df <- tibble(LOCATION=c("DEU","ITA","USA"),UNIT=c("DEU","EUR","USD"),value=c(120,140,160))
df
## A tibble: 3 x 3
#> LOCATION UNIT  value
#> <chr>    <chr> <dbl>
#> 1 DEU      DEU     120
#> 2 ITA      EUR     140
#> 3 USA      USD     160

df_labels <- list(LOCATION = data.frame(id =c("DEU","ITA","USA"), 
                                        label=c("Germany","Italy","United States")), 
                  UNIT = data.frame(id=c("USD","EUR"),
                                    label=c("Dollar","Euro")))
df_labels
#> $LOCATION
#>    id         label
#> 1 DEU       Germany
#> 2 ITA         Italy
#> 3 USA United States
#> 
#> $UNIT
#>    id  label
#> 1 USD Dollar
#> 2 EUR   Euro

我想要做的是將df中變量 LOCATION 和 UNIT 中的 ID 替換為df_labels提供的相應標簽。 我定義了以下函數:

get_labels <- function(x,db) {
     variable = deparse(substitute(x))
     return(factor(x,levels=db[[variable]]$id,labels=db[[variable]]$label))
     }

這樣我就可以在mutate使用它,如下所示:

df %>% mutate(LOCATION = get_labels(LOCATION,df_labels),
              UNIT = get_labels(UNIT,df_labels))
## A tibble: 3 x 3
#>   LOCATION      UNIT   value
#>   <fct>         <fct>  <dbl>
#> 1 Germany       Euro     120
#> 2 Italy         Euro     140
#> 3 United States Dollar   160

但是,我無法在多個列中使用該函數。 如果我嘗試使用across

df %>% mutate(across(where(is.character), ~get_labels(.,df_labels)))

結果是受影響列中的NA 顯然,問題在於deparse(substitute(.)) ,它沒有捕獲列名。 不幸的是,尋找類似的問題,比如這一次並沒有幫助。

across將無法訪問列名,因此deparsesubstitute技巧將不起作用。 試試這個版本:

get_labels <- function(x, y, db) {
  return(factor(x,levels=db[[y]]$id,labels=db[[y]]$label))
}

cols <- sapply(df, is.character)
df[cols] <- purrr::imap_dfc(df[cols], get_labels, db = df_labels)
df
# A tibble: 3 x 3
#  LOCATION      UNIT   value
#  <fct>         <fct>  <dbl>
#1 Germany       NA       120
#2 Italy         Euro     140
#3 United States Dollar   160

我們可以用deframemap來做到這一點

library(purrr)
library(dplyr)
library(tibble)
lst1 <- map(df_labels, deframe)
for(nm in names(lst1))  df <- df %>%
           mutate(!! nm := lst1[[nm]][!! rlang::sym(nm)])

-輸出

df
# A tibble: 3 x 3
#  LOCATION      UNIT   value
#  <chr>         <chr>  <dbl>
#1 Germany       <NA>     120
#2 Italy         Euro     140
#3 United States Dollar   160

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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