【问题标题】:R dplyr methods inside own functionR dplyr方法在自己的函数中
【发布时间】:2017-04-26 03:16:53
【问题描述】:

考虑对数据框进行这种 dplyr 处理:

existing.df <- filter(existing.df, justanEx > 0) %>%
                arrange(desc(justanEx)) %>%
                mutate(mean = mean(justanEx), 
                median = median(justanEx),
                rank = seq_len(length(anotherVar)))

我必须在我正在做的工作中做很多事情,所以我尝试为它制作一个函数:

df.overZ <- function(data, var){
        df <- data %>% filter(var > 0) %>%
                arrange_(desc((var))) %>%
                mutate(mean = mean(var),
                median = median(var),
                rank = seq_len(length(anotherVar)))
        df
} 

他们

existing.df <- df.overZ(existing.df, "realVar")

但这给了我这个错误:

Error in arrange_impl(.data, dots) : 
  incorrect size (1), expecting : 50000

如果我尝试:

existing.df <- df.overZ(existing.df, realVar)

我收到此错误:

Error in filter_impl(.data, dots) : obj 'realVar' not found

我已经尝试过filter_、arrange_和mutate_,

但没有任何意义。

这行得通吗?

但以下功能有效:

make.df <- function(var, n){
        df <- orign.df %>% filter(!is.na(var)) %>%
                select(1:2,n,3:6)
        df
}

existing.df <- make.df("oneVar",7)

【问题讨论】:

  • 错误信息是什么?另外,请提供一些示例数据(data.df的内容)。
  • 请使用dput 显示一个小示例数据以及基于此的预期输出
  • 添加了错误信息。请注意,这必须适用于现有的 data.frame,任何 data.frame。

标签: r function dplyr


【解决方案1】:

随着dplyr的开发版(即将发布0.6.0),我们可以使用quosures

library(dplyr)
df.overZ <- function(data, Var){
          Var <- enquo(Var)
         data %>%
               filter(UQ(Var) > 0) %>%
               arrange(desc(UQ(Var))) %>%
               mutate(Mean = mean(UQ(Var)),
                      Median = median(UQ(Var)),
                      rank = row_number())

 }

df.overZ(iris, Sepal.Length)

我们也可以扩展这个函数,使其具有group_by 选项

df.overZ2 <- function(data, Var, grpVar){
          Var <- enquo(Var)
          grpVar <- enquo(grpVar)
          newVar <- paste(quo_name(Var), c("Mean", "Median", "Rank"), sep="_")
         data %>%
               filter(UQ(Var) > 0) %>%
               arrange(desc(UQ(Var))) %>%
               group_by(UQ(grpVar)) %>%
               summarise(UQ(newVar[1]) := mean(UQ(Var)),
                      UQ(newVar[2]) := median(UQ(Var)),
                      UQ(newVar[3]) := n())

}

df.overZ2(iris, Sepal.Length, Species)
# A tibble: 3 × 4
#    Species Sepal.Length_Mean Sepal.Length_Median Sepal.Length_Rank
#      <fctr>             <dbl>               <dbl>             <int>
#1     setosa             5.006                 5.0                50
#2 versicolor             5.936                 5.9                50
#3  virginica             6.588                 6.5                50

在这里,enquobase R 中的 substitute 执行类似的工作,方法是获取输入参数并将其转换为 quosure,然后在函数 (filter/arrange/mutate/summarise/group_by) 中取消引用 (!!UQ) 来评估它。我们还可以通过在赋值的 lhs 上传递 quosure 来命名列 (:=)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 2015-12-31
    • 2016-11-29
    • 2019-08-08
    相关资源
    最近更新 更多