有没有办法用ggplot创建一个“星”图?

时间:2013-12-17 00:06:35

标签: r ggplot2

我正在尝试(部分)使用s.class(...)重现ade4ggplot中可用的群集图,但这个问题实际上更为通用。

注意:This question指的是“星形图”,但实际上只讨论了蜘蛛图。

df     <- mtcars[,c(1,3,4,5,6,7)]
pca    <-prcomp(df, scale.=T, retx=T)
scores <-data.frame(pca$x)

library(ade4)
km <- kmeans(df,centers=3)
plot.df <- cbind(scores$PC1, scores$PC2)
s.class(plot.df, factor(km$cluster))

我正在寻找的基本功能是“明星”,例如从公共点(此处为聚类质心)辐射到一些其他点(此处为聚类中的点)的一组线。

有没有办法使用ggplot包来做到这一点?如果不是直接通过ggplot,那么是否有人知道有效的加载项。例如,stat_ellipse(...)上有几个变体,它们不属于ggplot包(herehere)。

2 个答案:

答案 0 :(得分:6)

这个答案是基于@ agstudy的回复和@Henrik评论中提出的建议。发布,因为它更短,更直接适用于问题。

底线是这样的:使用ggplot geom_segment(...)可以轻松制作星图。使用问题中的df,pca,分数和km:

# build ggplot dataframe with points (x,y) and corresponding groups (cluster)
gg <- data.frame(cluster=factor(km$cluster), x=scores$PC1, y=scores$PC2)
# calculate group centroid locations
centroids <- aggregate(cbind(x,y)~cluster,data=gg,mean)
# merge centroid locations into ggplot dataframe
gg <- merge(gg,centroids,by="cluster",suffixes=c("",".centroid"))
# generate star plot...
ggplot(gg) +
  geom_point(aes(x=x,y=y,color=cluster), size=3) +
  geom_point(data=centroids, aes(x=x, y=y, color=cluster), size=4) +
  geom_segment(aes(x=x.centroid, y=y.centroid, xend=x, yend=y, color=cluster))

结果与使用s.class(...)获得的结果相同。

答案 1 :(得分:3)

这里的困难是创建数据而不是绘图本身。您应该浏览包的代码并提取它对您有用的内容。这应该是一个好的开始:

enter image description here

dfxy <- plot.df
df <- data.frame(dfxy)
x <- df[, 1]
y <- df[, 2]

fac <- factor(km$cluster)
f1 <- function(cl) {
  n <- length(cl)
  cl <- as.factor(cl)
  x <- matrix(0, n, length(levels(cl)))
  x[(1:n) + n * (unclass(cl) - 1)] <- 1
  dimnames(x) <- list(names(cl), levels(cl))
  data.frame(x)
}
wt = rep(1, length(fac))
dfdistri <- f1(fac) * wt
w1 <- unlist(lapply(dfdistri, sum))
dfdistri <- t(t(dfdistri)/w1)

## create a data.frame
cstar=2
ll <- lapply(seq_len(ncol(dfdistri)),function(i){
  z1 <- dfdistri[,i]
  z <- z1[z1>0]
  x <- x[z1>0]
  y <- y[z1>0]
  z <- z/sum(z)
  x1 <- sum(x * z)
  y1 <- sum(y * z)
  hx <- cstar * (x - x1)
  hy <- cstar * (y - y1)
  dat <- data.frame(x=x1, y=y1, xend=x1 + hx, yend=y1 + hy,center=factor(i))
})

dat <- do.call(rbind,ll)
library(ggplot2)
ggplot(dat,aes(x=x,y=y))+
  geom_point(aes(shape=center)) +
  geom_segment(aes(yend=yend,xend=xend,color=center,group=center))