在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:
- 直接返回ggplot对象,而不是分配中间变量
- 合并绘图调用
-
将库调用移到函数外部(无需在每次调用该函数时加载库).
- Return the ggplot object directly instead of assigning an intermediate variable
- Merged the plotting calls
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")