r - R - ggplot2 - ggplot(data, aes(x=variable...)) 和 ggplot(data, aes(x=data$variable...)) 之间的区别
问题描述
我目前在ggplot2中遇到了一个现象,如果有人能给我一个解释,我将不胜感激。
我需要在直方图上绘制一个连续变量,并且需要在图上表示两个分类变量。以下数据框就是一个很好的例子。
library(ggplot2)
species <- rep(c('cat', 'dog'), 30)
numb <- rep(c(1,2,3,7,8,10), 10)
groups <- rep(c('A', 'A', 'B', 'B'), 15)
data <- data.frame(species=species, numb=numb, groups=groups)
让下面的代码表示一个连续变量的分类。
data$factnumb <- as.factor(data$numb)
如果我想绘制这个数据集,以下两个代码是完全可以互换的:
注意fill=语句后的区别。
p <- ggplot(data, aes(x=factnumb, fill=species)) +
facet_grid(groups ~ .) +
geom_bar(aes(y=(..count..)/sum(..count..))) +
scale_y_continuous(labels = scales::percent)
q <- ggplot(data, aes(x=factnumb, fill=data$species)) +
facet_grid(groups ~ .) +
geom_bar(aes(y=(..count..)/sum(..count..))) +
scale_y_continuous(labels = scales::percent)
但是,当使用现实生活中的连续变量时,并非所有类别都包含观察值,我仍然需要在 x 轴上表示空类别,以便获得样本分布的近似值。为了演示这一点,我使用了以下代码:
data_miss <- data[which(data$numb!= 3),]
这导致分类变量的水平与数据集中的观察值之间存在差异:
> unique(data_miss$factnumb)
[1] 1 2 7 8 10
Levels: 1 2 3 7 8 10
并绘制了data_miss数据集,仍然包括factnumb变量的所有级别。
pm <- ggplot(data_miss, aes(x=factnumb, fill=species)) +
facet_grid(groups ~ .) +
geom_bar(aes(y=(..count..)/sum(..count..))) +
scale_fill_discrete(drop=FALSE) +
scale_x_discrete(drop=FALSE)+
scale_y_continuous(labels = scales::percent)
qm <- ggplot(data_miss, aes(x=factnumb, fill=data_miss$species)) +
facet_grid(groups ~ .) +
geom_bar(aes(y=(..count..)/sum(..count..))) +
scale_x_discrete(drop=FALSE)+
scale_fill_discrete(drop=FALSE) +
scale_y_continuous(labels = scales::percent)
在这种情况下,当使用fill=data_miss$species时,绘图的填充会发生变化(并且变得更糟)。
如果有人能帮我解决这个问题,我会非常高兴。
只是“运气”,在情节 1 和 2 的情况下填充是相同的,还是我在 ggplot2 的精细机械中偶然发现了一些微妙的错误?
提前致谢!
亲切的问候,
贝尔纳黛特
解决方案
在里面使用aes(data$variable)
从来都不好,从不推荐,也不应该使用。有时它仍然有效,但aes(variable)
始终有效,因此您应该始终使用aes(variable)
.
更多解释:
ggplot
使用非标准评估。标准评估R 函数只能看到全局环境中的对象。如果我有以mydata
列名命名的数据col1
,并且我这样做mean(col1)
了,我会收到一个错误:
mydata = data.frame(col1 = 1:3)
mean(col1)
# Error in mean(col1) : object 'col1' not found
发生此错误是因为col1
不在全局环境中。mydata
它只是数据框的列名。
该aes
函数在幕后做了额外的工作data
,除了检查全局环境外,还知道查看图层的列。
ggplot(mydata, aes(x = col1)) + geom_bar()
# no error
不过,您不必只在里面使用一列aes
。为了提供灵活性,您可以执行列的功能,甚至是您碰巧在现场定义的其他向量(如果它具有正确的长度):
# these work fine too
ggplot(mydata, aes(x = log(col1))) + geom_bar()
ggplot(mydata, aes(x = c(1, 8, 11)) + geom_bar()
col1
那么和 和有什么区别mydata$col1
呢?嗯,col1
是一个列的名称,并且mydata$col1
是实际值。ggplot
将在您的数据中查找名为 的列col1
,并使用它。mydata$col1
只是一个向量,它是完整的列。差异很重要,因为ggplot
经常进行数据操作。每当有方面或聚合函数时,ggplot 就会将您的数据分成几部分并做一些事情。为了有效地做到这一点,它需要知道识别数据和列名。当你给它时mydata$col1
,你并没有给它一个列名,你只是给它一个值向量 - 无论该列中发生什么,事情都不起作用。
aes()
因此,只需在without中使用不带引号的列名,data$
一切都会按预期工作。
推荐阅读
- python - Sort double dimensions list with a given column Python
- kubernetes - 在 Kubernetes 上快照 Kafka 集群的 PV
- r - Problem with Bayesian Network with bnlearn cpquery in shiny server - supplying evidence
- spring-boot - spring jdbc hikari connection pool - constantly logs on and off to database
- jquery - 尝试渲染代码时,它说“图表”未定义,但它在 jQuery 中。我没有正确调用 jQuery 吗?
- python - python 3'function'对象不可迭代
- react-native - How to Push Realm File to Internal Storage in React Native from Application
- c# - 从C#中的抽象类获取调用类名
- javascript - 使用 Js 为列表视图中的每个条目制作模式?
- oracle11g - Disable "where" under different conditions in the select in the apex oracle