我正在尝试(部分)使用s.class(...)
重现ade4
包ggplot
中可用的群集图,但这个问题实际上更为通用。
注意: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
包(here和here)。
答案 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)
这里的困难是创建数据而不是绘图本身。您应该浏览包的代码并提取它对您有用的内容。这应该是一个好的开始:
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))