我已经看过几篇关于如何用dplyr函数编写自己的函数的帖子.例如,您可以在此帖子中看到如何使用group_by (regroup)和.我认为看看我是否可以使用主要功能编写函数会很有趣.我希望我们可以进一步了解如何使用函数编写函数.summarisedplyrdplyr
数据
country <- rep(c("UK", "France"), each = 5)
id <- rep(letters[1:5], times = 2)
value <- runif(10, 50, 100)
foo <- data.frame(country, id, value, stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)
目标
我想在函数中编写以下过程.
foo %>%
mutate(new = ifelse(value > 60, 1, 0)) %>%
filter(id %in% c("a", "b", "d")) %>%
group_by(country) %>%
summarize(whatever = sum(value))
Run Code Online (Sandbox Code Playgroud)
尝试
### Here is a function which does the same process
myFun <- function(x, ana, bob, cathy) x %>%
mutate(new = ifelse(ana > 60, 1, 0)) %>%
filter(bob %in% c("a", "b", "d")) %>%
regroup(as.list(cathy)) %>%
summarize(whatever = sum(ana))
myFun(foo, value, id, "country")
Source: local data frame [2 x 2]
country whatever
1 France 233.1384
2 UK 245.5400
Run Code Online (Sandbox Code Playgroud)
你可能会意识到那arrange()不存在.这是我正在努力的那个.这是两个观察结果.第一个实验是成功的.这些国家的顺序从英国 - 法国变为法国 - 英国.但第二个实验并不成功.
### Experiment 1: This works for arrange()
myFun <- function(x, ana) x %>%
arrange(ana)
myFun(foo, country)
country id value
1 France a 90.12723
2 France b 86.64229
3 France c 74.93320
4 France d 80.69495
5 France e 72.60077
6 UK a 84.28033
7 UK b 67.01209
8 UK c 94.24756
9 UK d 79.49848
10 UK e 63.51265
### Experiment2: This was not successful.
myFun <- function(x, ana, bob) x %>%
filter(ana %in% c("a", "b", "d")) %>%
arrange(bob)
myFun(foo, id, country)
Error: incorrect size (10), expecting :6
### This works, by the way.
foo %>%
filter(id %in% c("a", "b", "d")) %>%
arrange(country)
Run Code Online (Sandbox Code Playgroud)
鉴于第一个实验是成功的,我很难理解为什么第二个实验失败了.在第二个实验中可能有一些事情要做有人有想法吗?感谢您抽出宝贵时间.
一旦问题352关闭,我就安装了dplyr 0.3和lazyeval,看看它如何在另一个函数中使用函数.在阅读了关于非标准评估的小插图之后,从lazyeval到结尾的新功能看起来就是一个选项.现在请注意替换.dplyrinterp_group_by_regroup
set.seed(16)
foo = data.frame(country = rep(c("UK", "France"), each = 5),
id = rep(letters[1:5], times = 2),
value = runif(10, 50, 100), stringsAsFactors = FALSE)
Run Code Online (Sandbox Code Playgroud)
首先是函数外的代码/结果:
library(lazyeval)
library(dplyr)
foo %>%
mutate(new = ifelse(value > 60, 1, 0)) %>%
filter(id %in% c("a", "b", "d")) %>%
group_by(country) %>%
summarize(whatever = sum(value))
Source: local data frame [2 x 2]
country whatever
1 France 213.0009
2 UK 207.8331
Run Code Online (Sandbox Code Playgroud)
然后将上面的过程变成一个函数:
myFun = function(x, ana, bob, cathy) {
x %>%
mutate_(new = interp(~ifelse(var > 60 , 1, 0), var = as.name(ana))) %>%
filter_(interp(~var %in% c("a", "b", "d"), var = as.name(bob))) %>%
group_by_(cathy) %>%
summarize_(whatever = interp(~sum(var), var = as.name(ana)))
}
Run Code Online (Sandbox Code Playgroud)
这给出了期望的结果.
myFun(foo, "value", "id", "country")
Source: local data frame [2 x 2]
country whatever
1 France 213.0009
2 UK 207.8331
Run Code Online (Sandbox Code Playgroud)
对于你的第二个问题arrange,我试过了
myfun2 = function(x, ana, bob) x%>%
filter_(interp(~var %in% c("a", "b", "d"), var = as.name(ana))) %>%
arrange_(as.name(bob))
myfun2(foo, "id", "country")
Run Code Online (Sandbox Code Playgroud)