【问题标题】:Pass a df and variable argument in a function in R在 R 中的函数中传递 df 和变量参数
【发布时间】:2019-01-15 14:53:20
【问题描述】:

如何编写一个带有 df 和变量参数的函数,同时评估两者?我从 r-bloggers 阅读了几篇文章和博客文章,我认为我对惰性评估有一些问题,但现在我非常困惑。

这是我的功能:

    RAM_char_func <- function(dataset, char_var){

      a <- dataset[ , c("id", char_var)]

      b <- a[[id]][is.na(a[[char_var]]) %in% FALSE]

      c <- a[a[[id]] %in% b , ]

      c


}

我明白了:

警告 未知或未初始化的列:“char_var”。

这应该给我一个表 (c),它有两列并基于 char_var n-amount 行。虽然代码在函数外部工作,但我无法让它在函数内部工作。我也尝试了使用选择和过滤的 tidyverse-idea,但这也不起作用。

我将 R 3.5.1 与 Mac OS X(High Sierra,10.13.6)和 R Studio(最新版本)一起使用。

数据框

df <- data.frame(id = c(1:10),
                          var_10 = c(101:110),
                          var_25 = c("a", "b", NA, "c", NA, "d", NA, "e", "f", NA),stringsAsFactors = F)
df

函数外的代码是:

a <- df[ , c("id", "v_25")]
a

b <- a$id[is.na(a$v_25) %in% FALSE]
b

c <- a[a$id %in% b , ]
c

library(tidyverse)
df %>%
select(id, var_25) %>%
filter(is.na(var_25) %in% FALSE)

【问题讨论】:

  • 请添加一个最小的工作示例和错误消息。据我所知,您可能必须将变量 id 解析为函数,但如果没有更多信息,这很难说。
  • 我确实添加了一个示例 df - 原始 df 包含大约 220 个变量,因此我对其进行了简化。谢谢
  • 我已更正您为 df 创建的数据。

标签: r function dataframe arguments


【解决方案1】:

这是解决问题的一种方法:

library(tidyverse)
library(rlang)

remove.na <- function(data, col){
    symcol <- enquo(col)
    data %>% select(id, !!symcol) %>% filter(!is.na(!!symcol))
}

df %>% remove.na(var_25)
#   id var_25
# 1  1      a
# 2  2      b
# 3  4      c
# 4  6      d
# 5  8      e
# 6  9      f

all_equal(df %>% select(id, var_25) %>% filter(!is.na(var_25)), df %>% remove.na(var_25))
[1] TRUE

【讨论】:

    【解决方案2】:

    本着“授人以渔”的精神,您可以使用reprex 包来确保您在干净的环境中运行您的错误代码,并且错误将非常明确(您也可以只要您没有凌乱的 Rprofile 文件,只需在新会话中运行代码):

    library(reprex)
    reprex({
    df <- data.frame(id = c(1:10),
                     var_10 = c(101:110),
                     var_25 = c("a", "b", NA, "c", NA, "d", NA, "e", "f", NA),stringsAsFactors = F)
    
    
    RAM_char_func <- function(dataset, char_var){
    
      a <- dataset[ , c("id", char_var)]
    
      b <- a[[id]][is.na(a[[char_var]]) %in% FALSE]
    
      c <- a[a[[id]] %in% b , ]
    
      c
    }
    RAM_char_func(df,"var_25")
    })
    

    如果您使用Rstudio,它将在查看器选项卡中显示输出,我得到的错误是:

    > (function(x, i, exact) if (is.matrix(i)) as.matrix(x)[[i]] else .subset2(x, : objet 'id' introuvable 中的错误

    (对不起法国人)

    它告诉你找不到对象id,然后你可以检查为什么你的代码试图访问一个名为id的对象,你会很容易在函数的第二条指令中找到错误。

    如果您很难找到有罪的行,请尝试在错误后立即运行traceback() 或调用debugonce(RAM_char_func) 然后RAM_char_func(df,"var_25") 并浏览直到找到失败的行。

    【讨论】:

    • 谢谢 beaucoup - 了解 reprex-package 将是我接下来的任务之一 - 但您的介绍非常有帮助!
    【解决方案3】:

    您的函数包含错误。 [[id]] 必须是 [["id"]]

    RAM_char_func <- function(dataset, char_var){
    
        a <- dataset[ , c("id", char_var)]
    
        b <- a[["id"]][is.na(a[[char_var]]) %in% FALSE]
    
        c <- a[a[["id"]] %in% b , ]
    
        c
    }
    

    数据:

    df <- data.frame(id = c(1:10),
                              var_10 = c(101:110),
                              var_25 = c("a", "b", NA, "c", NA, "d", NA, "e", "f", NA),stringsAsFactors = F)
    

    调用你的函数:

    RAM_char_func(dataset=df,char_var="var_25")
    
    #  id var_25
    #1  1      a
    #2  2      b
    #4  4      c
    #6  6      d
    #8  8      e
    #9  9      f
    

    【讨论】:

    • 是的 - 这也很好用!谢谢 - 你不知道,我在 base-R 版本中更改了多长时间的单个字符并且没​​有成功 - 谢谢!
    • 如果 1 小时的研究对您没有帮助。来这里,最好问一个问题。通常这是经验丰富的 R 程序员可以在眨眼之间看到的最小错误。
    猜你喜欢
    • 1970-01-01
    • 2012-04-12
    • 2014-09-08
    • 2020-10-21
    • 2019-10-15
    • 2021-12-12
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    相关资源
    最近更新 更多