美学必须是长度为一,或者与数据长度相同。问题:

38

我希望创建一个绘图,其中X值是测量数据的子集,Y值是另一个测量数据的子集。

以下示例中,我有4个产品p1、p2、p3和p4。每个产品都根据其偏斜度、颜色和版本进行定价。 我想创建一个多面板图,将P3产品(Y轴)与P1产品(X轴)相对比。

下面是我的尝试,但出现了以下错误:

Error: Aesthetics must either be length one, or the same length as the dataProblems:subset(price, product == "p1"), subset(price, product == "p3")

library(ggplot2)
product=c("p1","p1","p1","p1","p1","p1","p1","p1","p2","p2","p2","p2","p2","p2","p2","p2","p3","p3","p3","p3","p3","p3","p3","p3","p4","p4","p4","p4","p4","p4","p4","p4")
skew=c("b","b","b","b","a","a","a","a","b","b","b","b","a","a","a","a","b","b","b","b","a","a","a","a","b","b","b","b","a","a","a","a")
version=c(0.1,0.1,0.2,0.2,0.1,0.1,0.2,0.2,0.1,0.1,0.2,0.2,0.1,0.1,0.2,0.2,0.1,0.1,0.2,0.2,0.1,0.1,0.2,0.2,0.1,0.1,0.2,0.2,0.1,0.1,0.2,0.2)
color=c("C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2","C1","C2")
price=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32)
df = data.frame(product, skew, version, color, price)
# First plot all the data
p1 <- ggplot(df, aes(x=price, y=price, colour=factor(skew))) + geom_point(size=2, shape=19)
p1 <- p1 + facet_grid(version ~ color)
p1 # This gavea very good plot. So far so good
# Now plot P3 vs P1
p1 <- ggplot(df, aes(x=subset(price, product=='p1'), y=subset(price, product=='p3'), colour=factor(skew))) + geom_point(size=2, shape=19)
p1
# failed with: Error: Aesthetics must either be length one, or the same length as the dataProblems:subset(price, product == "p1"), subset(price, product == "p3")

这是我期望的结果:

这是我期望的结果


子集化数据框,而不是向量。 - joran
@joran:他可以这样使用子集:看看subset(df$price, df$product=='p1')。它等同于df$price[df$product == 'p1'] - David Robinson
@DavidRobinson 是的...我最终到达了那里。 - joran
2
问题在于 skewcolour=factor(skew) 中没有被子集化,因此长度不正确。 - David Robinson
5个回答

24

最好不要在aes()内部对变量进行子集,而是转换您的数据:

df1 <- unstack(df,form = price~product)
df1$skew <- rep(letters[2:1],each = 4)

p1 <- ggplot(df1, aes(x=p1, y=p3, colour=factor(skew))) + 
        geom_point(size=2, shape=19)
p1

22
问题在于 skew 没有在 colour=factor(skew) 中进行子集化,所以它的长度是错误的。由于 subset(skew, product == 'p1') 等同于 subset(skew, product == 'p3'),在这种情况下使用哪个子集都无所谓。因此你可以通过以下方式解决问题:
p1 <- ggplot(df, aes(x=subset(price, product=='p1'),
                     y=subset(price, product=='p3'),
                     colour=factor(subset(skew, product == 'p1')))) +
              geom_point(size=2, shape=19)

请注意,大多数R用户会将其简写为更加简洁的形式:
p1 <- ggplot(df, aes(x=price[product=='p1'],
                     y=price[product=='p3'],
                     colour=factor(skew[product == 'p1']))) +
              geom_point(size=2, shape=19)

嗨@DavidRobinson,你的解决方案非常好用,我已经尝试了建议的第二个。问题是,当我添加一个facet_grid(version〜color)时,我的所有数据点都会在4个facet中复制。有什么想法吗? - Riad

6
类似于 @joran 的答案。将数据框进行重塑,以便每种产品的价格位于不同列中:
xx <- reshape(df, idvar=c("skew","version","color"),
              v.names="price", timevar="product", direction="wide")

xx 将具有价格列 price.p1,... price.p4,因此:

ggp <- ggplot(xx,aes(x=price.p1, y=price.p3, color=factor(skew))) +
       geom_point(shape=19, size=5)
ggp + facet_grid(color~version)

该功能将从您的图像中提取结果。


1
我遇到了这个错误,是因为我在我的几何图形 (geom_text) 中指定了一个标签属性,但在顶层 aes 中指定了颜色。
df <- read.table('match-stats.tsv', sep='\t')
library(ggplot2)

# don't do this!
ggplot(df, aes(x=V6, y=V1, color=V1)) +
  geom_text(angle=45, label=df$V1, size=2)

为了解决这个问题,我将标签属性从geom中移出,并放到顶层的aes中。
df <- read.table('match-stats.tsv', sep='\t')
library(ggplot2)

# do this!
ggplot(df, aes(x=V6, y=V1, color=V1, label=V1)) +
  geom_text(angle=45, size=2)

0
我遇到了这个问题,因为数据集被错误地过滤了,导致结果数据框为空。即使以下操作也会导致错误显示:
ggplot(df, aes(x="", y = y, fill=grp))

因为df是空的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接