以下のようなプロットを作成します。
radarchart
パッケージの fmsb
関数を使用できることを知っています。かしら ggplot2
極座標を使用してこれを行うことができますか?ありがとう。
最初に、いくつかのパッケージをロードします。
library(reshape2)
library(ggplot2)
library(scales)
リンクしたレーダーチャートの例のデータを以下に示します。
maxmin <- data.frame(
total = c(5, 1),
phys = c(15, 3),
psycho = c(3, 0),
social = c(5, 1),
env = c(5, 1)
)
dat <- data.frame(
total = runif(3, 1, 5),
phys = rnorm(3, 10, 2),
psycho = c(0.5, NA, 3),
social = runif(3, 1, 5),
env = c(5, 2.5, 4)
)
Ggplotに適したものにするために、少しの操作が必要です。
それらを正規化し、id列を追加して、長い形式に変換します。
normalised_dat <- as.data.frame(mapply(
function(x, mm)
{
(x - mm[2]) / (mm[1] - mm[2])
},
dat,
maxmin
))
normalised_dat$id <- factor(seq_len(nrow(normalised_dat)))
long_dat <- melt(normalised_dat, id.vars = "id")
ggplotは、最初と最後の要因が一致するように値をラップします。これを回避するために、追加の因子レベルを追加します。 これはもはや真実ではありません。
levels(long_dat $ variable)<-c(levels(long_dat $ variable)、 "")
これがプロットです。まったく同じではありませんが、開始する必要があります。
ggplot(long_dat, aes(x = variable, y = value, colour = id, group = id)) +
geom_line() +
coord_polar(theta = "x", direction = -1) +
scale_y_continuous(labels = percent)
coord_polar
を使用すると、線が湾曲することに注意してください。直線が必要な場合は、別の手法を試す必要があります。
非極座標バージョンを探している場合、次の機能が役立つと思います:
###################################
##Radar Plot Code
##########################################
##Assumes d is in the form:
# seg meanAcc sdAcc meanAccz sdAccz meanSpd sdSpd cluster
# 388 -0.038 1.438 -0.571 0.832 -0.825 0.095 1
##where seg is the individual instance identifier
##cluster is the cluster membership
##and the variables from meanACC to sdSpd are used for the clustering
##and thus should be individual lines on the radar plot
radarFix = function(d){
##assuming the passed in data frame
##includes only variables you would like plotted and segment label
d$seg=as.factor(d$seg)
##find increment
angles = seq(from=0, to=2*pi, by=(2*pi)/(ncol(d)-2))
##create graph data frame
graphData= data.frame(seg="", x=0,y=0)
graphData=graphData[-1,]
for(i in levels(d$seg)){
segData= subset(d, seg==i)
for(j in c(2:(ncol(d)-1))){
##set minimum value such that it occurs at 0. (center the data at -3 sd)
segData[,j]= segData[,j]+3
graphData=rbind(graphData, data.frame(seg=i,
x=segData[,j]*cos(angles[j-1]),
y=segData[,j]*sin(angles[j-1])))
}
##completes the connection
graphData=rbind(graphData, data.frame(seg=i,
x=segData[,2]*cos(angles[1]),
y=segData[,2]*sin(angles[1])))
}
graphData
}
クラスターまたはグループ別にプロットする場合は、次を使用できます。
radarData = ddply(clustData, .(cluster), radarFix)
ggplot(radarData, aes(x=x, y=y, group=seg))+
geom_path(alpha=0.5,colour="black")+
geom_point(alpha=0.2, colour="blue")+
facet_wrap(~cluster)
これは、次のデータサンプルで動作するはずです。
seg meanAccVs sdAccVs meanSpd sdSpd cluster
1470 1.420 0.433 -0.801 0.083 1
1967 -0.593 0.292 1.047 0.000 3
2167 -0.329 0.221 0.068 0.053 7
2292 -0.356 0.214 -0.588 0.056 4
2744 0.653 1.041 -1.039 0.108 5
3448 2.189 1.552 -0.339 0.057 8
7434 0.300 0.250 -1.009 0.088 5
7764 0.607 0.469 -0.035 0.078 2
7942 0.124 1.017 -0.940 0.138 5
9388 0.742 1.289 -0.477 0.301 5
私はこの問題に数日を費やし、最終的にggradar
の上に 自分のパッケージ を構築することにしました。その中心は@Tony M.の機能の改良版です:
_CalculateGroupPath4 <- function(df) {
angles = seq(from=0, to=2*pi, by=(2*pi)/(ncol(df)-1)) # find increment
xx<-c(rbind(t(plot.data.offset[,-1])*sin(angles[-ncol(df)]),
t(plot.data.offset[,2])*sin(angles[1])))
yy<-c(rbind(t(plot.data.offset[,-1])*cos(angles[-ncol(df)]),
t(plot.data.offset[,2])*cos(angles[1])))
graphData<-data.frame(group=rep(df[,1],each=ncol(df)),x=(xx),y=(yy))
return(graphData)
}
CalculateGroupPath5 <- function(mydf) {
df<-cbind(mydf[,-1],mydf[,2])
myvec<-c(t(df))
angles = seq(from=0, to=2*pi, by=(2*pi)/(ncol(df)-1)) # find increment
xx<-myvec*sin(rep(c(angles[-ncol(df)],angles[1]),nrow(df)))
yy<-myvec*cos(rep(c(angles[-ncol(df)],angles[1]),nrow(df)))
graphData<-data.frame(group=rep(mydf[,1],each=ncol(mydf)),x=(xx),y=(yy))
return(graphData)
}
microbenchmark::microbenchmark(CalculateGroupPath(plot.data.offset),
CalculateGroupPath4(plot.data.offset),
CalculateGroupPath5(plot.data.offset), times=1000L)
Unit: microseconds
expr min lq mean median uq max neval
CalculateGroupPath(plot.data.offset) 20768.163 21636.8715 23125.1762 22394.1955 23946.5875 86926.97 1000
CalculateGroupPath4(plot.data.offset) 550.148 614.7620 707.2645 650.2490 687.5815 15756.53 1000
CalculateGroupPath5(plot.data.offset) 577.634 650.0435 738.7701 684.0945 726.9660 11228.58 1000
_
実際に比較していることに注意してください このベンチマークには他の関数もあります -とりわけggradar
の関数です。一般に、@ Tony Mのソリューションはよく書かれています-ロジックの意味で、それを他の多くの言語で使用できます。 Javascript、いくつかの調整。ただし、演算をベクトル化すると、R
ははるかに高速になります。したがって、私のソリューションでは計算時間が大幅に増加します。
@Tony M.を除くすべての回答では、_coord_polar
_の_ggplot2
_-関数を使用しています。デカルト座標系内にとどまることには4つの利点があります。
plotly
。scales
-パッケージを使用します。このスレッドを見つけたときにレーダープロットの実行方法について何も知らない場合:coord_polar()
は見栄えの良いレーダーを作成するかもしれません-プロット。ただし、実装には多少注意が必要です。試したとき、複数の問題がありました。
coord_polar()
は、例えばプロットに変換されません。この人は、ここで (素敵なレーダーチャート _coord_polar
_を使用して作成しました。
しかし、私の経験からすると、coord_polar()
- trickの使用はお勧めしません。代わりに、静的ggplot-radarを作成するための「簡単な方法」を探している場合は、多分ggforce
-- packageを使用してレーダーの円を描いてください。これは私のパッケージを使用するよりも簡単であるという保証はありませんが、適応性からは_coord_polar
_よりきれいだと思われます。ここでの欠点は、たとえばplotly
はggforce-extensionをサポートしていません。
編集:今、私は私の意見を少し修正したggplot2のcoord_polarでニースの例を見つけました。
Ggplotでほぼそれを行う回答を次に示します。
私はここに例を置くだけではありません。それはハドレーがここに示したものに基づいています https://github.com/hadley/ggplot2/issues/516
私がやったのは代わりにdeployer/tidyrを使用し、シンプルにするために3台の車だけを選択することでした
まだ保留中の問題は1)最後と最初の点が接続されていない、これはcoord_polarを従来のx軸のラッピングとして見れば明らかです。接続する理由はありません。しかし、それはレーダーチャートが通常2)表示される方法です。これを行うには、これらの2点間に手動でセグメントを追加する必要があります。少し操作して、さらにいくつかのレイヤーを追加する必要があります。時間があれば私はそれに取り組みます
library(dplyr);library(tidyr);library(ggplot2)
#make some data
data = mtcars[c(27,19,16),]
data$model=row.names(data)
#connvert data to long format and also rescale it into 0-1 scales
data1 <- data %>% gather(measure,value,-model) %>% group_by(measure) %>% mutate(value1=(value-min(value))/(max(value)-min(value)))
is.linear.polar <- function(coord) TRUE
ggplot(data1,aes(x=measure,y=value1,color=model,group=model))+geom_line()+coord_polar()
私は完璧なggplot互換のスパイダープロットを提供するこの素晴らしいライブラリに出会いました:
https://github.com/ricardo-bion/ggradar
Githubで確認できるように、インストールと使用が非常に簡単です。
devtools::install_github("ricardo-bion/ggradar", dependencies=TRUE)
library(ggradar)
suppressPackageStartupMessages(library(dplyr))
library(scales)
library(tibble)
mtcars %>%
rownames_to_column( var = "group" ) %>%
mutate_at(vars(-group),funs(rescale)) %>%
tail(4) %>% select(1:10) -> mtcars_radar
ggradar(mtcars_radar)