gpt4 book ai didi

r - 尝试在自定义函数中重用 dplyr 代码块;我错过了什么?

转载 作者:行者123 更新时间:2023-12-02 04:12:17 25 4
gpt4 key购买 nike

Hadley 说,“当你复制和粘贴代码块超过两次时,你应该考虑编写一个函数”——我经常在 dplyr 中写这个链:

df %>%
group_by(col) %>%
summarise(n = n()) %>%
mutate(percent = round((n / sum(n)) * 100, 2) %>%
arrange(desc(n))

我想创建一个使用两个参数执行此操作的函数:数据框和变量或列名。这就是我现在正在尝试的:

value_counts = function(df, col) {
group_by_(df, col) %>%
summarise_(n = n()) %>%
mutate_(percent = round((n / sum(n)) * 100, 2)) %>%
arrange(desc(n))
}

它不起作用,我已经尝试了该网站上的其他一些建议,但我不太明白它们是如何工作的,例如:

value_counts = function(df, col) {
group_by_(df, .dots = col) %>%
summarise_(n = n()) %>%
mutate_(percent = round((n / sum(n)) * 100, 2)) %>%
arrange(desc(n))
}

我真的很想编写一个使用管道并依赖于 dplyr 的函数。我可以继续编写反复运行的代码,但我想开始在 R 中编写有用的函数以节省时间。

我是 geom_text() 的忠实粉丝,喜欢快速轻松地在数据框中获取来自 dplyr 的信息,这样我就可以快速制作大量图表!

我应该阅读的任何资源或要遵循的链接都会很有用。谢谢!

最佳答案

@jenesaisquoi 的回答很好,但每当我编写 dplyr-y 函数时,我都会尝试以与该包中类似的样式来编写它们。我想要一对 SE 和 NSE 函数,您可以在其中使用裸变量名。

一些注意事项。

  • 我摆脱了管道 (%>%) 使它们稍微更快并且更容易调试。管道在交互式使用中非常方便,但我在编写函数时倾向于避免使用它们。
  • 我在所有使用包特定函数的地方都使用了::。这意味着您现在无需加载 dplyr 即可使用该功能。
  • 我认为没有理由将使用仅限于一列,因此提出了一个 ... 参数,它接受根据需要按任意多的列进行分组。
  • 请参阅vignette(NSE) 了解有关使用lazyeval 包的更多详细信息,以及dplyr 处理 的方式。 ...dots.

函数

value_counts <- function(df, ...) {
value_counts_(df, .dots = lazyeval::lazy_dots(...))
}

value_counts_ <- function(df, ..., .dots) {
dots <- lazyeval::all_dots(.dots, ..., all_named = TRUE)
df <- dplyr::group_by_(df, .dots = dots)
df <- dplyr::summarise(df, n = n())
df <- dplyr::mutate(df, percent = round(n / sum(n) * 100, 2))
df <- dplyr::arrange(df, desc(n))
return(df)
}

例子

value_counts(mtcars, cyl)
value_counts(mtcars, cyl, vs)

value_counts_(mtcars, ~cyl)
value_counts_(mtcars, ~cyl, ~vs)
value_counts_(mtcars, .dots = list(~cyl, ~vs))

而且您可以轻松地将它们与其他 dplyr 动词连接在一起:

library(dplyr)
mtcars %>%
filter(cyl != 4) %>%
value_counts()

关于r - 尝试在自定义函数中重用 dplyr 代码块;我错过了什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35967860/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com