【问题标题】:Use dplyr coalesce in programming在编程中使用 dplyr coalesce
【发布时间】:2017-07-30 22:49:13
【问题描述】:

我想同时使用 dplyr 的 programming magic,新到版本 0.7.0,到 coalesce 两列。下面,我列出了我的一些尝试。

df <- data_frame(x = c(1, 2, NA), y = c(2, NA, 3))

# What I want to do:
mutate(df, y = coalesce(x, y))

# Here's the expected output:
#> # A tibble: 3 x 2
#>       x     y
#>   <dbl> <dbl>
#> 1     1     1
#> 2     2     2
#> 3    NA     3

我认为fn1 会起作用,但它会将varname 视为右侧的字符。

fn1 <- function(varname) {
  mutate(df, UQ(varname) := coalesce(x, !!varname))
}
fn1("y")
# Error in mutate_impl(.data, dots) : 
#   Evaluation error: Argument 2 must be type double, not character. 

enquo 的另一次尝试:

fn2 <- function(varname) {
  varname <- enquo(varname)
  mutate(df, varname := coalesce(x, !!varname))
}
fn2("y")  # same error

也许我可以与!!! 拼接? (剧透:我不能。)

fn3 <- function(varname) {
  varnames <- c("x", varname)
  mutate(df, UQ(varname) := coalesce(!!! varnames))
}
fn3("y")
#> # A tibble: 3 x 2
#>       x     y
#>   <dbl> <chr>
#> 1     1     x
#> 2     2     x
#> 3    NA     x

fn4 <- function(varname) {
  varnames <- quo(c("x", varname))
  mutate(df, UQ(varname) := coalesce(!!! varnames))
}
fn4("y")
# Error in mutate_impl(.data, dots) : 
#   Column `y` must be length 3 (the number of rows) or one, not 2 

【问题讨论】:

  • 不得不说这种大喊大叫!!!不是我最喜欢的dplyr更新,太让人迷惑了

标签: r dplyr rlang


【解决方案1】:

右侧的varname需要使用!!sym

library(rlang)
fn1 <- function(varname) {
  mutate(df, !!varname := coalesce(x, !!sym(varname)))
}

fn1("y")

# A tibble: 3 x 2
#      x     y
#  <dbl> <dbl>
#1     1     1
#2     2     2
#3    NA     3

或者使用UQ:

fn1 <- function(varname) {
    mutate(df, UQ(varname) := coalesce(x, UQ(sym(varname))))
}

【讨论】:

    【解决方案2】:

    以下两种方法都可以。

    library(dplyr)
    
    # Define a function to apply coalesce
    col_fun1 <- function(df, Cols){
      df2 <- df %>%
        mutate(y = coalesce(!!!as.list(df %>% select(UQ(Cols)))))
      return(df2)
    }
    
    # Test the function
    col_fun1(df = df, Cols = c("x", "y"))
    # A tibble: 3 x 2
          x     y
      <dbl> <dbl>
    1     1     1
    2     2     2
    3    NA     3
    

    或者试试这个。

    # Define a function to apply coalesce
    col_fun2 <- function(df, Cols){
      df2 <- df %>%
        mutate(y = coalesce(!!!as.list(df[, Cols])))
      return(df2)
    }
    
    # Test the function
    col_fun2(df = df, Cols = c("x", "y"))
    # A tibble: 3 x 2
          x     y
      <dbl> <dbl>
    1     1     1
    2     2     2
    3    NA     3
    

    【讨论】:

      猜你喜欢
      • 2017-12-26
      • 2017-12-23
      • 1970-01-01
      • 2014-10-08
      • 2018-11-17
      • 1970-01-01
      • 2019-01-07
      • 2018-06-19
      • 2014-02-23
      相关资源
      最近更新 更多