geom_density2d的等效重量

时间:2014-01-22 03:19:46

标签: r ggplot2

考虑以下数据:

   contesto       x       y perc
1       M01  81.370 255.659   22
2       M02  85.814 242.688   16
3       M03  73.204 240.526   33
4       M04  66.478 227.916   46
5      M04a  67.679 218.668   15
6       M05  59.632 239.325   35
7       M06  64.316 252.777   23
8       M08  90.258 227.676   45
9       M09 100.707 217.828   58
10      M10  89.829 205.278   53
11      M11 114.998 216.747   15
12      M12 119.922 235.482   18
13      M13 129.170 239.205   36
14      M14 142.501 229.717   24
15      M15  76.206 213.144   24
16      M16  30.090 166.785   33
17      M17 130.731 219.989   56
18      M18  74.885 192.336   36
19      M19  48.823 142.645   32
20      M20  48.463 186.361   24
21      M21  74.765 205.698   16

我想为perc加权的点x和y创建一个二维密度图。通过使用rep

,我可以做到这一点(虽然我没有想到)
library(ggplot2)

dataset2 <- with(dataset, dataset[rep(1:nrow(dataset), perc),])

ggplot(dataset2, aes(x, y)) + 
    stat_density2d(aes(alpha=..level.., fill=..level..), size=2, 
        bins=10, geom="polygon") + 
    scale_fill_gradient(low = "yellow", high = "red") +
    scale_alpha(range = c(0.00, 0.5), guide = FALSE) +
    geom_density2d(colour="black", bins=10) +
    geom_point(data = dataset) +
    guides(alpha=FALSE) + xlim(c(10, 160)) + ylim(c(120, 280))

enter image description here

这似乎不是正确的方法,因为其他geom允许加权,如:

dat <- as.data.frame(ftable(mtcars$cyl))
ggplot(dat, aes(x=Var1)) + geom_bar(aes(weight=Freq))

但是如果我在这里尝试使用重量,则该图与数据不匹配(desc被忽略):

ggplot(dataset, aes(x, y)) + 
    stat_density2d(aes(alpha=..level.., fill=..level.., weight=perc), 
        size=2, bins=10, geom="polygon") + 
    scale_fill_gradient(low = "yellow", high = "red") +
    scale_alpha(range = c(0.00, 0.5), guide = FALSE) +
    geom_density2d(colour="black", bins=10, aes(weight=perc)) +
    geom_point(data = dataset) +
    guides(alpha=FALSE) + xlim(c(10, 160)) + ylim(c(120, 280))

enter image description here

是否使用rep来衡量密度的正确方法,还是有更好的方法类似于weight的{​​{1}}参数?

geom_bar方法看起来像用基数R做的内核密度所以我假设它应该是这样的:

enter image description here

rep

2 个答案:

答案 0 :(得分:3)

如果您的权重是每个坐标(或按比例)的#观察值,我认为您做得对。该函数似乎期望所有观察结果,如果在原始数据集上调用它,则无法动态更新ggplot对象,因为它已经建模了密度,并包含派生的绘图数据。

如果您的真实数据集很大,您可能希望使用data.table代替with(),它的速度提高了约70倍。例如在这里看到1m co-ords,具有1-20次重复(在该示例中> 10m观察)。但是,对于660个观测值没有性能相关性(无论如何,该图可能是您使用大型数据集的性能瓶颈)。

bigtable<-data.frame(x=runif(10e5),y=runif(10e5),perc=sample(1:20,10e5,T))

system.time(rep.with.by<-with(bigtable, bigtable[rep(1:nrow(bigtable), perc),]))
#user  system elapsed 
#11.67    0.18   11.92

system.time(rep.with.dt<-data.table(bigtable)[,list(x=rep(x,perc),y=rep(y,perc))])
#user  system elapsed 
#0.12    0.05    0.18

# CHECK THEY'RE THE SAME
sum(rep.with.dt$x)==sum(rep.with.by$x)
#[1] TRUE    

# OUTPUT ROWS
nrow(rep.with.dt)
#[1] 10497966

答案 1 :(得分:0)

添加上面的答案,您还可以使用带有data.table的string = """Date,Open,High,Low,Close,Volume,Adj Close 2016-01-08,1.658,1.70,1.625,1.639,15383400,1.639 2016-01-07,1.64,1.645,1.56,1.642,28015800,1.642 2016-01-06,1.68,1.734,1.672,1.71,15199200,1.71""" string = string.split('\n')[1:] 公式。

似乎比@ Troy的data.table答案稍慢,但仍比data.frame rep快得多。如果你有很多列重复,它的优点是更方便;如果列rep

list(x=rep(x,perc), y=rep(y,perc))会很麻烦

基准:

x,y,z,a,b,c,d...