【问题标题】:In R Creating flexible functions that works with different types of input在 R 中创建适用于不同类型输入的灵活函数
【发布时间】:2023-03-09 01:23:02
【问题描述】:

我想知道如何让 R 函数灵活地适应不同类型的输入,例如向量、列表、数据框和小标题。请参阅下面的示例。特别想知道:

有更好的方法吗? 在解决这个问题时,是否有不同的方面需要考虑?

# Example data
x <- c(1, 2)
y <- c(1, 2)

# Example function
add_numbers <- function(x, y){
  z <- x+y
  z
}
add_numbers(x, y)

# They function does not work with lists as input!
x_list <- list(c(1, 2))
y_list <- list(c(1, 2))
add_numbers(x_list, y_list)

# The 2 examples below works, but provide different names for column in output.
x_tb <- tibble::as_tibble_col(c(1, 2))
y_tb <- tibble::as_tibble_col(c(1, 2))
z_tb <- add_numbers(x_tb, y_tb)
z_tb$value # Note the column name is different in output

x_df <- as.data.frame(c(1, 2))
y_df <- as.data.frame(c(1, 2))
z_df <- add_numbers(x_df, y_df)
z_df$`c(1, 2)` # Note the column name is different in output


# Potential solution for a more flexibl function
add_numbers_flexible <- function(x, y) {
  
  # If vec make tibble
  if(is.vector(x)  && length(x)>1) {
    x <- tibble::as_tibble_col(x)
  }
  if(is.vector(y)  && length(y)>1) {
    y <- tibble::as_tibble_col(y)
  }
  
  # Sort out if input is list
  if(is.list(x)){
    x <- tibble::as_tibble_col(x[[1]])
  }
  if(is.list(y)){
    y <- tibble::as_tibble_col(y[[1]])
  }
  
  # Sort out if input is data.frame
  if(is.data.frame(x)){
    colnames(x) <- "value"
  }
  if(is.data.frame(y)){
    colnames(y) <- "value"
  }
  
  z <- x+y
  z
}

# These now works, providing similar output
add_numbers_flexible(x, y)
add_numbers_flexible(x_list, y_list)
add_numbers_flexible(x_df, y_df)
add_numbers_flexible(x_tb, y_tb)

【问题讨论】:

    标签: r


    【解决方案1】:

    对于这个特定的示例,在添加之前unlisting 每个对象将适用于所有示例用例。

    x <- c(1, 2); y <- c(1, 2)
    x_list <- list(c(1, 2)); y_list <- list(c(1, 2))
    x_tb <- tibble::as_tibble_col(c(1, 2)); y_tb <- tibble::as_tibble_col(c(1, 2))
    x_df <- as.data.frame(c(1, 2)); y_df <- as.data.frame(c(1, 2))
    
    add_numbers_flex2 <- function(x, y) {
        x2 <- unlist(x)
        y2 <- unlist(y)
        return(x2 + y2)
    }
    
    add_numbers_flex2(x,y)
    #> [1] 2 4
    add_numbers_flex2(x_list, y_list)
    #> [1] 2 4
    add_numbers_flex2(x_tb, y_tb)
    #> value1 value2 
    #>      2      4
    add_numbers_flex2(x_df, y_df)
    #> c(1, 2)1 c(1, 2)2 
    #>        2        4
    

    事实上,它甚至可以通过混合类型来工作,尽管我不确定天气是否可取:

    add_numbers_flex2(x_df, y)
    #> c(1, 2)1 c(1, 2)2 
    #>        2        4
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-20
      • 1970-01-01
      • 2023-03-10
      • 2015-12-02
      • 2021-11-22
      相关资源
      最近更新 更多