默认情况下使用相同名称的美学与R中的ggplot?

log*_*thy 6 r ggplot2

有时使用ggplot我发现自己使用数据框,其中变量名实际上对应于我想要使用的美学.这会导致像这样的代码:

rect <- data.frame(xmin=1,xmax=10,ymin=1,ymax=10)
ggplot(rect, aes(xmin=xmin,xmax=xmax,ymin=ymin,ymax=ymax))+geom_rect()
Run Code Online (Sandbox Code Playgroud)

感觉有点湿.

有没有办法避免这种重复?

bap*_*ste 15

aes_auto(),但它明显被弃用了.或者,

aes_all(names(rect))
Run Code Online (Sandbox Code Playgroud)

  • 好的ggarchaeology @baptiste! (2认同)

hrb*_*str 6

更新:请参阅@ baptiste的回答.这是(现已弃用)功能的75% aes_auto().

data.frame@MrFlick对#spiffy解决方案的一种更快捷但特定的替代方案:

#' Generate ggplot2 aesthetic mappings from data.frame columns
#' 
#' Use this like you would \code{aes()} or \code{aes_string()} but
#' pass in the \code{data.frame} you want to use for the mapping.
#' By default this will use all the column names from the input
#' \code{data.frame} so use column selections if you don't want 
#' to map them all.
#' 
#' @param df data.frame
aes_from_df <- function(df) {

  mapping <- setNames(as.list(colnames(df)), colnames(df))
  mapping <- lapply(mapping, function(x) {
    if (is.character(x)) parse(text = x)[[1]] else x
  })
  structure(ggplot2:::rename_aes(mapping), class="uneval")

}

rect <- data.frame(xmin=1, xmax=10, ymin=1,  ymax=10)

ggplot(rect, aes_from_df(rect)) + geom_rect()
Run Code Online (Sandbox Code Playgroud)


MrF*_*ick 5

如果真的出现了很多,你可以创建自己的帮助函数

aes_self <- function(...) {
    dots <- as.list(substitute(...()))
    names <- sapply(dots, paste)
    do.call("aes", setNames(dots, names))
}

ggplot(rect, aes_self(xmin, xmax, ymin, ymax))+geom_rect()
Run Code Online (Sandbox Code Playgroud)

而且我还要添加一个,以便更容易混合固定美学.在这里你可以使用"." 表示与参数同名的列:

aes_dotself <- function(...) {
    dots <- as.list(substitute(...()))
    self <- sapply(dots, function(x) x==as.name("."))
    if(any(self)) {
        dots[self] <- sapply(names(dots[self]), as.name)
    }
    do.call("aes", dots)
}

rect <- data.frame(xmin=1,xmax=10,ymin=1,ymax=10, type="type1")
ggplot(rect, aes_dotself(xmin=.,xmax=.,ymin=.,ymax=., fill=type))+geom_rect()
Run Code Online (Sandbox Code Playgroud)