10

我有以下数据集(样本):

train <- data.frame(ps_ind_06_bin = c(FALSE, FALSE, FALSE, TRUE, TRUE, FALSE),
                        ps_ind_07_bin = c(FALSE, TRUE, TRUE, FALSE, TRUE, TRUE),
                        ps_ind_08_bin = c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE),
                        ps_ind_09_log = c(1, 3, 4, 2, 3, 2))

我有以下函数显示group_by()操作的 ggplot:

get_charts1 <- function(mygroup){
  quo_var <- enquo(mygroup)
  train %>% 
    group_by(!!quo_var) %>% 
    count() %>%
    ungroup() %>%
  ggplot(aes_q(x = quo_var, y = quote(n), fill = quo_var)) + 
    geom_col() +
    theme(legend.position = "none")
    }

当我手动输入列名时它工作正常,例如:

get_charts1(ps_ind_07_bin)

但是,我想在几个列上使用这个函数,我把它放在一个向量上:

binarias <- train %>% 
             select(ends_with("bin")) %>% 
             colnames()

使用地图并采取一些建议,我尝试使用:

listaplots <- map(quo(!!! syms(binarias)), get_charts1)

但这给了我以下错误:

"Error: Can't splice at top-level"

有谁知道我需要做什么才能让它工作?

4

3 回答 3

15

我将首先创建一个 reprex (您非常接近,但忘记加载所需的包),然后使用styler将样式重新设置为一致的格式:

library(tidyverse)
library(rlang)

train <- data.frame(
  ps_ind_06_bin = c(FALSE, FALSE, FALSE, TRUE, TRUE, FALSE),
  ps_ind_07_bin = c(FALSE, TRUE, TRUE, FALSE, TRUE, TRUE),
  ps_ind_08_bin = c(TRUE, TRUE, TRUE, FALSE, TRUE, FALSE),
  ps_ind_09_log = c(1, 3, 4, 2, 3, 2)
)

get_charts <- function(mygroup) {
  quo_var <- enquo(mygroup)
  train %>%
    group_by(!! quo_var) %>%
    count() %>%
    ungroup() %>%
    ggplot(aes_q(x = quo_var, y = quote(n), fill = quo_var)) +
    geom_col() +
    theme(legend.position = "none")
}

你想自动生成这样的代码:

get_charts(ps_ind_06_bin)
get_charts(ps_ind_07_bin)
get_charts(ps_ind_08_bin)

这将需要一个 for 循环或一个 apply/map 函数。Amap() 在这里工作得很好,因为我们想要返回 ggplot2 对象,而使用 for 循环来做这件事需要更多的基础设施。一旦你记得你需要在这里使用符号而不是原始字符串,这很简单

vars <- train %>% select(ends_with("bin")) %>% colnames()

vars %>%
  syms() %>%
  map(function(var) get_charts(!!var))

## [[1]]

## 
## [[2]]

## 
## [[3]]

于 2017-12-18T15:38:47.030 回答
2

而不是map,我想你想要invoke_map这里。这似乎给了你想要的

listaplots  <- invoke_map(get_charts1, rlang::syms(binarias))

map()似乎强制评估参数,而没有invoke_map

于 2017-12-18T15:25:34.580 回答
1

更改enquo()sym(),您的代码可以正常工作,如下所示:

get_charts1 <- function(mygroup){
    quo_var <- sym(mygroup)  # <- HERE

    train %>% 
      group_by(!!quo_var) %>% 
      count() %>%
      ungroup() %>%
      ggplot(aes_q(x = quo_var, y = quote(n), fill = quo_var)) + 
      geom_col() +
      theme(legend.position = "none")
}

binarias <- train %>% select(ends_with("bin")) %>% colnames()

binarias %>% map(get_charts1)
于 2017-12-18T15:31:17.027 回答