如何在dplyr管道中引用data.frame变量。编程?

时间:2015-02-13 18:41:05

标签: r ggplot2 dplyr

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的每个元素。

3 个答案:

答案 0 :(得分:3)

因此,您需要设置一个变量来保存分组变量的名称,因为tbl_df调用后summarize()对象中的“分组依据”变量信息不会保留。你可以这样做

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)}

不需要

答案 1 :(得分:1)

据我所知,这必须分三部分完成。我发现有一些限制,如果我弄错了,我会很感激有人纠正。

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)

尝试完成所有一次调用我遇到了这些问题:

  1. 无法阻止ggplot自动排序x轴,而无需在调用之前重置变量的级别。 ggplot调用中唯一的方法是使用reorder,据我所知,aes_string无法与mutate一起使用。
  2. 我的另一个想法是使用s_mutate来重置关卡。我们需要使用dplyrExras中的mutate函数来使用字符串,但是从管道数据集中重置级别似乎不会起作用。
  3. 该陈述将与mutate(THEME_NAME = factor(THEME_NAME, levels=unique(THEME_NAME))) 一样(BTW有效):

    s_mutate(my_var = factor(my_var, levels = unique(my_var)))
    

    但是使用字符串接受版本时,级别保持不变:

    {{1}}

答案 2 :(得分:1)

这里分享的想法很有用,但这是我实际上最终要做的事情:

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())
}