在R中使用ggplot将变量传递给函数

问题描述:

我提供了一个用于绘制PCA图的功能,如下所示.我想传递主要组件的名称(变量a和b),但没有找到一种方法来执行此操作.我尝试使用aes_string.收到的错误是eval(expr,envir,enclos)中的错误:找不到对象".names"

I have a function provided to do a PCA plot which is shown below. I want to pass the names of the principal components(variables a and b) but have not figured a way to do this. I have tried using aes_string. Error received is Error in eval(expr, envir, enclos) : object '.names' not found

根据下面的建议,我举了一个具体的例子.一个在该函数起作用的地方,另一个在不起作用的地方.目标是将变量传递给该函数.

Per suggestion below, I have put a concrete example. One where the function works and another where it does not. Goal is to pass variables to this function.

 #data
  d = iris[1:4]
  #########################################################################
  # PCA_Plot functions
  #########################################################################

  PCA_Plot = function(pcaData)
  {
    library(ggplot2)

    theta = seq(0,2*pi,length.out = 100)
    circle = data.frame(x = cos(theta), y = sin(theta))
    p = ggplot(circle,aes(x,y)) + geom_path()

    loadings = data.frame(pcaData$rotation, .names = row.names(pcaData$rotation))
    p + geom_text(data=loadings, mapping=aes(x = PC1, y = PC2, label = .names, colour = .names, fontface="bold")) +
      coord_fixed(ratio=1) + labs(x = "PC1", y = "PC2")
  }
  # non-working function with two extra variables
  PCA_Plot2 = function(pcaData, var1, var2)
  {
    library(ggplot2)

    theta = seq(0,2*pi,length.out = 100)
    circle = data.frame(x = cos(theta), y = sin(theta))
    p = ggplot(circle,aes(x,y)) + geom_path()

    loadings = data.frame(pcaData$rotation, .names = row.names(pcaData$rotation))
    p + geom_text(data=loadings, mapping=aes(x = var1, y = var2, label = .names, colour = .names, fontface="bold")) +
      coord_fixed(ratio=1) + labs(x = var1, y = var2)
  }


  #pca
  library(stats)
  p = prcomp(d)

  PCA_Plot(p) #works

  PCA_Plot2(p, "PC1", "PC2") # ERROR Error: Discrete value supplied to 
  continuous scale

您几乎已经使用 aes_string 了!您正在提供 var1 var2 作为字符串,但没有提供 label 美观的 .names .如果将其更改为.names" ,则功能将起作用.

You were almost there with aes_string! You are providing var1 and var2 as strings, but not the label aesthetic .names. If you change that to ".names", your function will work.

我对您的功能做了一些改动:

I altered your function a bit:

  1. 直接返回ggplot对象,而不是分配中间变量
  2. 合并绘图调用
  3. 将库调用移到函数外部(无需在每次调用该函数时加载库).

  1. Return the ggplot object directly instead of assigning an intermediate variable
  2. Merged the plotting calls
  3. Moved the library call outside of the function (no need to load the library every time you call the function).

library(stats)
library(ggplot2)

PCA_Plot2 = function(pcaData, var1, var2)
{

  theta = seq(0,2*pi,length.out = 100)

   circle = data.frame(x = cos(theta), y = sin(theta))

   loadings = data.frame(pcaData$rotation,  .names = row.names(pcaData$rotation))

  ggplot(circle, aes(x,y)) +
    geom_path() +
    geom_text(aes_string(x = var1, y = var2, label = ".names"), inherit.aes = FALSE, data = loadings) +
    coord_fixed(ratio=1) +
    labs(x = var1, y = var2)
}

PCA_Plot2(p, "PC1", "PC2")