列名中的破折号产生 "object not found" 错误

Dash in column name yields "object not found" Error

我有一个从数据生成散点图的函数,其中向 select 提供了一个参数用于为点着色的列。这是一个简化版本:

library(ggplot2)

plot_gene <- function (df, gene) {
   ggplot(df, aes(x, y)) + 
     geom_point(aes_string(col = gene)) +
     scale_color_gradient()
}

其中 df 是一个 data.frame,包含列 xy,然后是一堆基因名称。这对大多数基因名称都适用;然而,有些有破折号,但这些失败了:

print(plot_gene(df, "Gapdh")) # great!
print(plot_gene(df, "H2-Aa")) # Error: object "H2" not found

似乎正在解析 gene 变量("H2-Aa" 变为 H2 - Aa)。我该如何解决这个问题?有没有办法表明字符串不应在 aes_string 中经过 eval

可重现的输入

如果你需要一些输入来玩,这就像我的数据一样失败:

df <- data.frame(c(1,2), c(2,1), c(1,2), c(2,1))
colnames(df) <- c("x", "y", "Gapdh", "H2-Aa")

对于我的真实数据,我使用 read.table(..., header=TRUE) 并获取带有破折号的列名,因为原始数据文件有它们。

通常 R 会非常努力地确保您的 data.frame 中的列名可以是有效的变量名。使用非标准列名(那些不是有效变量名的列名)将在使用使用非标准评估类型语法的函数时导致问题。当专注于使用此类变量名时,您通常必须将它们用反引号括起来。正常情况下

ggplot(df, aes(x, y)) + 
  geom_point(aes(col = H2-Aa)) +
  scale_color_gradient()
# Error in FUN(X[[i]], ...) : object 'H2' not found

会return一个错误但是

ggplot(df, aes(x, y)) + 
  geom_point(aes(col = `H2-Aa`)) +
  scale_color_gradient()

会起作用。

如果确实需要,您可以粘贴反引号

geom_point(aes_string(col = paste0("`", gene, "`")))

或者您可以从一开始就将其视为符号并使用 aes_q instread

geom_point(aes_q(col = as.name(gene)))

ggplot 的最新版本支持通过 !! 转义,而不是使用 aes_stringaes_q,因此您可以

geom_point(aes(col = !!rlang::sym(gene)))