ggplot2 aes_string()无法处理以数字开头或包含空格的名称

Ali*_*Ali 11 r ggplot2

如果a的列名data.frame以数字开头,或者有空格,则aes_string()无法处理它们:

foo=data.frame("1st Col"=1:5, "2nd Col"=5:1, check.names=F)
bar=colnames(foo)
ggplot(foo, aes_string(x=bar[1],y=bar[2])) + geom_point()
# Error in parse(text = x) : <text>:1:2: unexpected symbol
# 1: 1st
#     ^

foo=data.frame("First Col"=1:5, "Second Col"=5:1, check.names=F)
bar=colnames(foo)
ggplot(foo, aes_string(x=bar[1],y=bar[2])) + geom_point()
# Error in parse(text = x) : <text>:1:7: unexpected symbol
# 1: First Col
#          ^

foo=data.frame("First_Col"=1:5, "Second_Col"=5:1, check.names=F)
bar=colnames(foo)
ggplot(foo, aes_string(x=bar[1],y=bar[2]))+geom_point()
# Now it works
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

有没有办法在列名中有空格,或者它们是以数字开头的,我们可以在ggplot2中使用它们吗?请考虑我们可能不知道列名称,因此请避免提供具有常量列名称的示例 - 如下所示:

aes_string(x=`1st Col`, y=`2nd Col`)
Run Code Online (Sandbox Code Playgroud)

seb*_*n-c 10

据我所知,这个方法应该以编程方式工作:

foo=data.frame("1st Col"=1:5, "2nd Col"=5:1, check.names=F)

#Save the colnames
bar=colnames(foo)

#change the names to something usable
names(foo) <- c("col1", "col2")

#Plot with arbitrary labs
ggplot(foo, aes(x=col1, y=col2)) + geom_point()+
  labs(x=bar[1], y=bar[2])
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述


小智 7

原始问题询问如何修改变量的值,以便在事先不知道值时ggplot()可以接受.

编写一个函数,在函数值的开头和结尾添加反向标记:

# ggName -> changes a string so it is enclosed in back-ticks.
#   This can be used to make column names that have spaces (blanks)
#   or non-letter characters acceptable to ggplot2.
#   This version of the function is vectorized with sapply.
ggname <- function(x) {
    if (class(x) != "character") {
        return(x)
    }
    y <- sapply(x, function(s) {
        if (!grepl("^`", s)) {
            s <- paste("`", s, sep="", collapse="")
        }
        if (!grepl("`$", s)) {
            s <- paste(s, "`", sep="", collapse="")
        }
    }
    )
    y 
}
Run Code Online (Sandbox Code Playgroud)

例子:

ggname(12)
Run Code Online (Sandbox Code Playgroud)

[1] 12

ggname("awk ward")
Run Code Online (Sandbox Code Playgroud)

"`awk ward`"

l <- c("awk ward", "no way!")
ggname(l)
Run Code Online (Sandbox Code Playgroud)

"`awk ward`""`没办法!`"

  • 谢谢!为了我的目的,我使用了一个简化版本:```paste("`",x,"`",sep ="")```. (4认同)

Sté*_*ent 5

您可以使用下面的函数aes_string2来代替aes_string

aes_string2 <- function(...){
  args <- lapply(list(...), function(x) sprintf("`%s`", x))
  do.call(aes_string, args)
}
Run Code Online (Sandbox Code Playgroud)