将列名传递给ggplot2中的图形函数

Passing column names into graph function in ggplot2

我有一个包含多个因变量但只有两个自变量的大型数据集(我将一遍又一遍地使用它来对许多因变量进行排序)。每个因变量测量两次,一次在治疗前,一次在治疗后。我想编写一个函数,允许我为这些多个因变量中的每一个获取一个图表,函数的参数作为我希望绘制的任何一个因变量的两个列名。

我生成了一个玩具数据集来说明我的问题。 't1DV1' 和 't1DV2' 是因变量 1 的治疗前和 post- 治疗得分。't1DV2' 和 't2DV2' 是治疗前和 post-因变量 2 的治疗得分。'group' 是自变量。

group <- factor(rep(c("A", "B"), 10))
t1DV1 <- runif(20, min = 0, max = 10)
t2DV1 <- runif(20, min = 0, max = 10)
t1DV2 <- runif(20, min = 0, max = 10)
t2DV2 <- runif(20, min = 0, max = 10)

df <- data.frame(group, t1DV1, t2DV1, t1DV2, t2DV2)

df

我试着写了下面的函数

DVGraph <- function (DV1, DV2) { 

require(tidyr)

dfLong <- gather(df, prePost, Score, DV1:DV1)

require(ggplot2)

barGraph <- ggplot(dfLong, aes(group, Score, fill = prePost)) + 
  geom_bar(stat = "identity", position = "dodge", size = 0.5) +
  scale_fill_manual(values = c("#999999", "#666666")) +
  xlab("") +
  ylab("Scores") +
  theme_bw()

return(barGraph)

}

然后尝试使用第一个重复测量变量调用它(我同样可以使用第二个,即 t1DV2 和 t2DV2)

DVGraph(t1DV1, t2DV1)

但是我得到一个错误。

我试过像这样使用引号

DVGraph("t1DV1", "t2DV1")

但是我遇到了另一个(不同的)错误。

有人知道我该怎么做吗?

将您的 gather 调用更改为以下内容:

dfLong <- gather(df, prePost, Score, DV1, DV2)

然后当你调用你的函数时,使用列号而不是列名:

DVGraph(2, 3)

或者,您可以将 gather() 替换为 melt(),从 reshape2 替换为 substitute(),以便能够使用未加引号的变量调用函数:

DVGraph <- function (DV1, DV2) { 

  require(tidyr)
  require(reshape2)

  dfLong <- melt(df,measure.vars = c(substitute(DV1),substitute(DV2)),
                 var="prePost",value.name ="Score")

  require(ggplot2)

  barGraph <- ggplot(dfLong, aes(group, Score, fill = prePost)) + 
    geom_bar(stat = "identity", position = "dodge", size = 0.5) +
    scale_fill_manual(values = c("#999999", "#666666")) +
    xlab("") +
    ylab("Scores") +
    theme_bw()

  return(barGraph)

}

DVGraph(t1DV2, t2DV1)

更新:

如果您想按照评论中的要求进行操作,一个快速解决方法是认识到使用 substitute() 会强制您的矢量成为列表,但您可以通过使用as.character(substitute())如下:

createFrame <- function (DV1, DV2) { 
  extractCols <- c("group", as.character(substitute(DV1)), as.character(substitute(DV2)))
  newFrame <- df[,extractCols]
  return(newFrame) 
}

createFrame(t1DV1, t2DV1)