如何通过 .dplyr 管道引用 data.frame 变量。以编程方式?
How to refer to a data.frame variable in a dplyr pipeline via . programmatically?
library(ggplot2)
library(dplyr)
library(scales)
data <- data.frame(THEME_NAME = c(rep("A", 10), rep("B", 20), rep("C", 15)))
data %>%
group_by(THEME_NAME) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
# THE NEXT LINE !!! #
ggplot(., aes(x = reorder(THEME_NAME, desc(freq)), y = freq)) +
geom_bar(stat="identity") +
scale_y_continuous(labels=percent)
如何以编程方式引用 THEME_NAME
?我可以 .$THEME_NAME
,但我想称其为 .[1]
或 select(., 1)
或类似性质的东西?
这样做的原因是我想在更大的上下文中使用这个管道——比如通过这个管道传递一堆因子变量。类似于:vars.to.plot <- sapply(data, is.factor)
然后 运行 vars.to.plot
的每个元素通过此管道。
据我所知,这必须分三部分完成。我发现有一些限制,如果我弄错了,我将不胜感激。
data <- data.frame(THEME_NAME = c(rep("A", 10), rep("B", 20), rep("C", 15)))
my_var <- names(data)[1]
df <- data %>%
group_by_(my_var) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
arrange(desc(freq))
df[[1]] <- factor(df[[1]], levels = unique(df[[1]]))
ggplot(df, aes_string(x = my_var, y = "freq")) +
geom_bar(stat="identity") +
scale_y_continuous(labels=percent)
为了解决所有问题,我 运行 遇到了这些问题:
- 没有办法阻止
ggplot
在调用之前不重置变量级别的情况下自动对 x 轴进行排序。 ggplot
调用中的唯一方法是使用 reorder
,据我所知,它不能与 aes_string
. 一起使用
- 我的另一个想法是使用
mutate
重置关卡。人们需要使用 dplyrExras
中的 s_mutate
函数来使用字符串,但从管道数据集中重置级别似乎对字符串不起作用。
声明在 mutate
中看起来像这样(顺便说一句,这很有效):
mutate(THEME_NAME = factor(THEME_NAME, levels=unique(THEME_NAME)))
但是对于接受版本的字符串,级别保持不变:
s_mutate(my_var = factor(my_var, levels = unique(my_var)))
所以你需要设置一个变量来保存分组变量的名称,因为在 summarize()
调用之后 "group by" 变量信息显然没有保存在 tbl_df
对象中.你可以这样做
varname<-"THEME_NAME"
data %>%
group_by_(varname) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
ggplot(eval(bquote(aes(x=reorder(.(as.name(varname)), desc(freq)), y=freq)))) +
geom_bar(stat="identity") +
scale_y_continuous(labels=percent)
此处使用 bquote()
动态构建 aes()
调用。这只是因为您要执行的 reorder()
步骤。否则使用 aes_string()
或其他东西会容易得多。
如果您总是想根据第一列重新排序(这意味着您永远不会按多个变量分组),您可以这样做
data %>%
group_by(THEME_NAME) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
{ggplot(., eval(substitute(aes(x=reorder(X, desc(freq)), y=freq), list(X=as.name(names(.)[1]))))) +
geom_bar(stat="identity") +
scale_y_continuous(labels=percent)}
不需要
这里分享的想法很有用,但这是我最终做的事情:
library(ggplot2)
library(dplyr)
library(scales)
data <- data.frame(THEME_NAME = c(rep("A", 10), rep("B", 20), rep("C", 15)),
THEME_NAME_2 = c(rep("E", 5), rep("F", 40)),
Non_Factor = 1:45)
factor.vars <- sapply(data, is.factor)
varnames <- names(data)[factor.vars]
myReorder <- function(x) {
factor(x, levels=names(sort(table(x), decreasing=TRUE)))
}
for (i in seq_along(varnames)) {
data[, varnames[i]] <- myReorder(data[, varnames[i]])
}
for (i in seq_along(varnames)) {
print(ggplot(data, aes_string(x = varnames[i], y = "..count../sum(..count..)")) +
geom_histogram())
}
library(ggplot2)
library(dplyr)
library(scales)
data <- data.frame(THEME_NAME = c(rep("A", 10), rep("B", 20), rep("C", 15)))
data %>%
group_by(THEME_NAME) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
# THE NEXT LINE !!! #
ggplot(., aes(x = reorder(THEME_NAME, desc(freq)), y = freq)) +
geom_bar(stat="identity") +
scale_y_continuous(labels=percent)
如何以编程方式引用 THEME_NAME
?我可以 .$THEME_NAME
,但我想称其为 .[1]
或 select(., 1)
或类似性质的东西?
这样做的原因是我想在更大的上下文中使用这个管道——比如通过这个管道传递一堆因子变量。类似于:vars.to.plot <- sapply(data, is.factor)
然后 运行 vars.to.plot
的每个元素通过此管道。
据我所知,这必须分三部分完成。我发现有一些限制,如果我弄错了,我将不胜感激。
data <- data.frame(THEME_NAME = c(rep("A", 10), rep("B", 20), rep("C", 15)))
my_var <- names(data)[1]
df <- data %>%
group_by_(my_var) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
arrange(desc(freq))
df[[1]] <- factor(df[[1]], levels = unique(df[[1]]))
ggplot(df, aes_string(x = my_var, y = "freq")) +
geom_bar(stat="identity") +
scale_y_continuous(labels=percent)
为了解决所有问题,我 运行 遇到了这些问题:
- 没有办法阻止
ggplot
在调用之前不重置变量级别的情况下自动对 x 轴进行排序。ggplot
调用中的唯一方法是使用reorder
,据我所知,它不能与aes_string
. 一起使用
- 我的另一个想法是使用
mutate
重置关卡。人们需要使用dplyrExras
中的s_mutate
函数来使用字符串,但从管道数据集中重置级别似乎对字符串不起作用。
声明在 mutate
中看起来像这样(顺便说一句,这很有效):
mutate(THEME_NAME = factor(THEME_NAME, levels=unique(THEME_NAME)))
但是对于接受版本的字符串,级别保持不变:
s_mutate(my_var = factor(my_var, levels = unique(my_var)))
所以你需要设置一个变量来保存分组变量的名称,因为在 summarize()
调用之后 "group by" 变量信息显然没有保存在 tbl_df
对象中.你可以这样做
varname<-"THEME_NAME"
data %>%
group_by_(varname) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
ggplot(eval(bquote(aes(x=reorder(.(as.name(varname)), desc(freq)), y=freq)))) +
geom_bar(stat="identity") +
scale_y_continuous(labels=percent)
此处使用 bquote()
动态构建 aes()
调用。这只是因为您要执行的 reorder()
步骤。否则使用 aes_string()
或其他东西会容易得多。
如果您总是想根据第一列重新排序(这意味着您永远不会按多个变量分组),您可以这样做
data %>%
group_by(THEME_NAME) %>%
summarise(n = n()) %>%
mutate(freq = n / sum(n)) %>%
{ggplot(., eval(substitute(aes(x=reorder(X, desc(freq)), y=freq), list(X=as.name(names(.)[1]))))) +
geom_bar(stat="identity") +
scale_y_continuous(labels=percent)}
不需要
这里分享的想法很有用,但这是我最终做的事情:
library(ggplot2)
library(dplyr)
library(scales)
data <- data.frame(THEME_NAME = c(rep("A", 10), rep("B", 20), rep("C", 15)),
THEME_NAME_2 = c(rep("E", 5), rep("F", 40)),
Non_Factor = 1:45)
factor.vars <- sapply(data, is.factor)
varnames <- names(data)[factor.vars]
myReorder <- function(x) {
factor(x, levels=names(sort(table(x), decreasing=TRUE)))
}
for (i in seq_along(varnames)) {
data[, varnames[i]] <- myReorder(data[, varnames[i]])
}
for (i in seq_along(varnames)) {
print(ggplot(data, aes_string(x = varnames[i], y = "..count../sum(..count..)")) +
geom_histogram())
}