我正在绘制一个 y 变量与多个 x 变量的关系图。我有一个使用 lapply 的工作解决方案。但是,我无法将 x 变量的名称写为每个图的 x 标签。这是我所拥有的一个简化示例:
目标是针对每个 x 变量绘制 y 变量,从而生成三个图,并将每个 x 变量的名称添加为 x 轴标签。
生成一个包含 1 个 y 变量和 3 个 x 变量的数据框:
df <- data.frame(y.variable=c(11:20), x1=c(21:30),x2=c(1:10),x3=c(31:40))
Run Code Online (Sandbox Code Playgroud)
一个应该以字符串形式检索变量名称的函数:
get_name <- function(v1) {deparse(substitute(v1))}
Run Code Online (Sandbox Code Playgroud)
生成 y 相对于 x 变量的图的函数:
generate_plot <- function(x.variable) {ggplot(data = df, aes(x.variable, y.variable )) +geom_point() + xlab(get_name(variable.name))}
Run Code Online (Sandbox Code Playgroud)
调用 lapply 对 df 的每一列执行generate_plot:
lapply(df, generate_plot)
Run Code Online (Sandbox Code Playgroud)
这会产生三个图,每个图都将“variable.x”作为其 x 标签,而不是所需的变量名称 x1、x2 和 x3。
我过去使用过!!sym(),没有任何令人难忘的头痛。
但是,现在当我尝试这样做时出现错误:
library(rlang)
library(tidyverse)
diamond_plot <- function (data, group, metric) {
quo_group <- sym(group)
quo_metric <- sym(metric)
data %>%
group_by(!! quo_group) %>%
summarise(price = mean(!! quo_metric)) %>%
ggplot(aes(x = !! quo_group, y = !! quo_metric)) +
geom_col()
}
diamond_plot(diamonds, "clarity", "price")
Run Code Online (Sandbox Code Playgroud)
错误是
Error in !quo_group : invalid argument type
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
我正在尝试生成 10 对图,每页图有几对,并使用循环for来构造这些图对。但是,这些图会作为单独的图而不是页面发送到设备。
下面的 MWE 对于基础图形和ggplot版本具有相同的结构,但基础图形可以工作,也ggplot可以不工作。我需要做什么才能使第二个版本中的分页正确?
library(ggplot2)
attach(mtcars)
# correct configuration
par(mfrow=c(2,2))
for (ii in 1:3){
vars <- c("wt", "disp", "wt")
plot(get(vars[ii]), mpg)
hist(get(vars[ii]))
}
# places each on separate plot
par(mfrow=c(2,2))
for (ii in 1:3){
vars <- c("wt", "disp", "wt")
p <- ggplot(mtcars, aes(get(vars[ii]), mpg)) + geom_point(size=4)
plot(p)
p <- ggplot(mtcars, aes(get(vars[ii]))) + geom_histogram()
plot(p)
}
detach(mtcars)
Run Code Online (Sandbox Code Playgroud) 我正在一个长数据库(full_database)上运行一个函数,该数据库有两个主要组,我需要在每个组的多个子集上执行各种线性模型。
然后,我将 R^2、调整后的 R^2 和 p.value 提取到数据框中,其中每一行对应于一次比较。由于有 30 种不同的情况,我有另一个小标题,其中列出了函数参数所在的所有可能性( possibility )。
原始函数的脚本是:
database_correlation <- function(id, group) {
require(dplyr)
require(tidyr)
require(rlang)
id_name <- quo_name(id)
id_var <- enquo(id)
group_name <- quo_name(group)
group_var <- enquo(group)
corr_db <- full_database %>%
filter(numid==!!id_name) %>%
filter(major_group==!!group_name) %>%
droplevels()
correlation <- summary(lm(yvar~xvar, corr_db))
id.x <- as.character(!!id_var) #Gives out an error: "invalid argument type"
group.x <- as.character(!!group_var) #Gives out an error: "invalid argument type"
r_squared <- correlation$r.squared
r_squared_adj <- correlation$adj.r.squared
p_value <- correlation$coefficients[2,4]
data.frame(id.x, group.x, r_squared, r_squared_adj, …Run Code Online (Sandbox Code Playgroud) 我已经连续几天尝试了这段代码的数百种排列,试图获得一个能够完成我想要的功能的函数,但我最终放弃了。感觉这绝对是可行的,而且我已经很接近了!
我试图通过下面的代表回到这里的核心问题。
基本上我有一个单行数据框,其中一列包含字符串列表(“概念”)。我想为每个字符串创建一个附加列,mutate最好使用从字符串中获取其名称的列,然后使用函数调用的结果填充该列(?哪个函数并不重要,对于现在?-我只需要该功能的基础设施就可以工作。)
像往常一样,我觉得我一定错过了一些明显的东西......也许只是一个语法错误。我还想知道是否需要使用purrr::map,也许更简单的矢量化映射可以正常工作。
我觉得新列的命名..1而不是概念名称这一事实可以说明问题所在。
我可以通过手动调用每个概念来创建我想要的数据框架(请参阅 reprex 的结尾),但由于不同数据框架的概念列表不同,我想使用管道和 tidyverse 技术来实现此功能,而不是手动执行。
我已阅读以下问题来寻求帮助:
但这些都没有完全帮助我解决我遇到的问题。[编辑:在最后一个q中添加到该列表中,这可能是我需要的技术]。
<!-- language-all: lang-r -->
# load packages -----------------------------------------------------------
library(rlang)
library(dplyr)
library(tidyr)
library(magrittr)
library(purrr)
library(nomisr)
# set up initial list of tibbles ------------------------------------------
df <- list(
district_population = tibble(
dataset_title = "Population estimates - local authority based …Run Code Online (Sandbox Code Playgroud) 我的问题与this 问题类似,但我需要跨列应用更复杂的函数,并且我不知道如何将 Lionel 建议的解决方案应用到具有作用域动词 likefilter_at()或filter()+across()等价物的自定义函数。{{{}}}看起来并没有引入“superstache”/运算符。
这是我想要做的一个非编程示例(不使用 NSE):
library(dplyr)
library(magrittr)
foo <- tibble(group = c(1,1,2,2,3,3),
a = c(1,1,0,1,2,2),
b = c(1,1,2,2,0,1))
foo %>%
group_by(group) %>%
filter_at(vars(a,b), any_vars(n_distinct(.) != 1)) %>%
ungroup
#> # A tibble: 4 x 3
#> group a b
#> <dbl> <dbl> <dbl>
#> 1 2 0 2
#> 2 2 1 2
#> 3 3 2 0
#> 4 3 2 1
Run Code Online (Sandbox Code Playgroud)
我还没有找到filter_at与filter+相同的行across() …
我想编写一个通用weighted_summarise()函数,它将自动解析和转换用户调用的函数调用的形式:
data %>% weighted_summarise(weights, a = sum(b), c = mean(d))
Run Code Online (Sandbox Code Playgroud)
进入委托给的实际调用dplyr::summarise
data %>% dplyr::summarise(a = sum(weights * b), c = mean(weights * d))
Run Code Online (Sandbox Code Playgroud)
这里,a和c是要在缩减数据中创建的新列, 和b是d中weights的现有列data。
理想情况下,我希望我像调用“native”一样调用我的函数dplyr::summarise,但有一个额外的weights参数散布到每个聚合函数中。
weighted_summarise <- function(data, weights, ...) {
data %>% dplyr::summarise(
# how to manipulate the ... and inject the weights in each name-value pair?
)
}
Run Code Online (Sandbox Code Playgroud)
问题如何操作省略号,以便weights将其注入到每个名称-值对的适当位置?我想以某种方式捕获 AST 并系统地遍历它并操作它。
对于某些对象,属性标识特殊列,例如对象中的几何列sf。为了在其中进行一些计算,dplyr最好能够轻松识别这些列。我正在寻找一种方法来创建一个有助于识别此列的函数。在下面的示例中,我可以创建一个函数来标识该列,但我仍然需要使用rlang拼接运算符 ( !!!)。
require(sf)\nrequire(dplyr)\nn<-4\ndf = st_as_sf(data.frame(x = 1:n, y = 1:n, cat=gl(2,2)), coords = 1:2, crs = 3857) %>% group_by(cat)\n# this is the example I start from however the geometry column is not guaranteed to have that name\ndf %>% mutate(d=st_distance(geometry, geometry[row_number()==1]))\n#> Simple feature collection with 4 features and 2 fields\n#> Geometry type: POINT\n#> Dimension: XY\n#> Bounding box: xmin: 1 ymin: 1 xmax: 4 ymax: 4\n#> Projected CRS: WGS 84 / Pseudo-Mercator\n#> # …Run Code Online (Sandbox Code Playgroud) 我想了解如何将表示表达式的字符串传递给dplyr,以便将字符串中提到的变量计算为数据帧中列的表达式.关于这个主题的主要内容包括传递,并且根本不讨论字符串.
很明显,在表示表达式时,quosures比字符串更安全,更清晰,所以当使用quosures时我们当然应该避免使用字符串.但是,在使用R生态系统之外的工具(例如javascript或YAML配置文件)时,通常需要使用字符串而不是quosures.
例如,假设我想要一个使用用户/调用者传入的表达式进行分组计数的函数.正如预期的那样,以下代码不起作用,因为dplyr使用非标准求值来解释参数group_by.
library(tidyverse)
group_by_and_tally <- function(data, groups) {
data %>%
group_by(groups) %>%
tally()
}
my_groups <- c('2 * cyl', 'am')
mtcars %>%
group_by_and_tally(my_groups)
#> Error in grouped_df_impl(data, unname(vars), drop): Column `groups` is unknown
Run Code Online (Sandbox Code Playgroud)
在dplyr 0.5中,我们将使用标准评估group_by_(.dots = groups)来处理这种情况.既然下划线动词已弃用,我们应该如何在dplyr 0.7中执行此类操作?
在只是列名的表达式的特殊情况下,我们可以使用这个问题的解决方案,但它们不适用于更复杂的表达式,例如2 * cyl不仅仅是列名.
是否可以使用purrr返回一个quosures列表?
foo <- c(1:3)
purrr::map(foo, rlang::quo(. + 2))
Run Code Online (Sandbox Code Playgroud)
返回已评估的quosures(即包含3到5的列表).
有没有办法返回包含quo(1 + 2),quo(2 + 2)等的列表?
(包版本如果重要或未来访问过:purrr 0.2.5,rlang 0.2.1).