[英]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
將無法訪問列名,因此deparse
, substitute
技巧將不起作用。 試試這個版本:
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
我們可以用deframe
和map
來做到這一點
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.