在mutate_if调用中提取列名

kat*_*ath 5 r dplyr nse

我想在函数调用中提取列名mutate_if.有了这个,我想在另一个表中查找一个值,并用查找值填充缺失值.我尝试使用quosure语法,但它无法正常工作.是否有可能直接提取列名?

样本数据

df <- structure(list(x = 1:10, 
               y = c(1L, 2L, 3L, NA, 1L, 2L, 3L, NA, 1L, 2L), 
               z = c(NA, 2L, 3L, NA, NA, 2L, 3L, NA, NA, 2L), 
               a = c("a", "b", "c", "d", "e", "a", "b", "c", "d", "e")), 
          .Names = c("x", "y", "z", "a"), 
          row.names = c(NA, -10L), 
          class = c("tbl_df", "tbl", "data.frame"))
df_lookup <- tibble(x = 0L, y = 5L, z = 8L)
Run Code Online (Sandbox Code Playgroud)

不工作

它不能直接以某种方式提取名称.

df %>% 
  mutate_if(is.numeric, funs({
    x <- .
    x <- enquo(x)
    lookup_value <- df_lookup %>% pull(quo_name(x))
    x <- ifelse(is.na(x), lookup_value, x)
    return(x)
  }))
Run Code Online (Sandbox Code Playgroud)

通过额外的功能,我能够提取名称,但随后替换不再起作用.

custom_mutate <- function(v) {
  v <- enquo(v)
  lookup_value <- df_lookup %>% pull(quo_name(v))

  # ifelse(is.na((!!v)), lookup_value, (!!v))
}

df %>% 
  mutate_if(is.numeric, funs(custom_mutate(v = .)))
Run Code Online (Sandbox Code Playgroud)

作品

如果我将其df作为附加参数添加到我的自定义函数中,它可以工作,但有没有办法没有这个?这感觉是错的,而不是如何dplyr...如果我错了,请纠正我;)
除此之外,我必须使用UQE而不是!!像在dplyr编程中所说的那样:

UQE()仅供专家使用

custom_mutate2 <- function(v, df) {
  v <- enquo(v)
  lookup_value <- df_lookup %>% pull(quo_name(v))

  df %>% 
    mutate(UQE(v) := ifelse(is.na((!!v)), lookup_value, (!!v))) %>% 
    pull(!!v)
}

df %>% 
  mutate_if(is.numeric, funs(custom_mutate2(v = ., df = df)))
Run Code Online (Sandbox Code Playgroud)

预期产出

# A tibble: 10 x 4
#        x     y     z a    
#    <int> <int> <int> <chr>
#  1     1     1     8 a    
#  2     2     2     2 b    
#  3     3     3     3 c    
#  4     4     5     8 d    
#  5     5     1     8 e    
#  6     6     2     2 a    
#  7     7     3     3 b    
#  8     8     5     8 c    
#  9     9     1     8 d    
# 10    10     2     2 e   
Run Code Online (Sandbox Code Playgroud)

Jul*_*rre 6

你必须使用quo而不是enquo

#enquo(.) :
<quosure: empty>
~function (expr) 
{
    enexpr(expr)
}
...

#quo(.) :
<quosure: frame>
~x
<quosure: frame>
~y
<quosure: frame>
~z
Run Code Online (Sandbox Code Playgroud)

用你的例子:

mutate_if(df, is.numeric, funs({
  lookup_value <- df_lookup %>% pull(quo_name(quo(.)))
  ifelse(is.na(.), lookup_value, .)
}))

# A tibble: 10 x 4
       x     y     z a    
   <int> <int> <int> <chr>
 1     1     1     8 a    
 2     2     2     2 b    
 3     3     3     3 c    
 4     4     5     8 d    
 5     5     1     8 e    
 6     6     2     2 a    
 7     7     3     3 b    
 8     8     5     8 c    
 9     9     1     8 d    
10    10     2     2 e    
Run Code Online (Sandbox Code Playgroud)