ctree()
軸が垂直になるようにターミナルノードをどのように回転させることができるのか疑問に思って分析した分類木があります。
library(party)
data(iris)
attach(iris)
plot(ctree(Species ~ Sepal.Length + Sepel.Width
+ Petal.Length + Petal.Width, data = iris))
ctree()
軸が垂直になるようにターミナルノードをどのように回転させることができるのか疑問に思って分析した分類木があります。
library(party)
data(iris)
attach(iris)
plot(ctree(Species ~ Sepal.Length + Sepel.Width
+ Petal.Length + Petal.Width, data = iris))
これが私がそれについてどうやって行くかです。最短の答えではありませんが、私は可能な限り徹底的にしたかったのです。
ツリーをプロットしているので、適切なプロット関数のドキュメントを確認することをお勧めします。
library(party)
data(iris)
attach(iris)
ctree <- ctree(Species ~ Sepal.Length + Sepal.Width
+ Petal.Length + Petal.Width, data = iris)
# getting ctree's class
> class(ctree)
[1] "BinaryTree"
attr(,"package")
[1] "party"
見てみると、引数?'plot.BinaryTree'
の次の説明が表示されます。terminal_panel
ターミナルノードをプロットするformfunction(node)のオプションのパネル関数。または、引数xおよびtp_argsを使用して呼び出され、パネル関数を設定するクラス「grapcon_generator」のパネル生成関数。デフォルトでは、従属変数のスケールに応じて適切なパネル関数が選択されます。
ドキュメントのさらに下には、へのリンクがあり?node_barplot
ます。これは私がデフォルトとして使用されていたと私が推測したものであり、以下を呼び出すことは推測が正しいことを証明しました:
plot(ctree, terminal_panel = node_barplot(ctree))
(出力は元のグラフと同じです)。
残念ながら、のパラメータはありhorizontal
ません。この関数のコードを見ると、プロンプトで入力するだけで、グラフがビューポートを使用して「手動で」描画されていることがわかります。残念ながら、私が先に進むために見つけることができた唯一の方法は、この関数を編集することでした。私は自分の変更をできるだけ明白にしようとしました:horiz
node_barplot
node_barplot
# Note inclusion of horiz = FALSE
alt_node_barplot <- function (ctreeobj, col = "black", fill = NULL, beside = NULL,
ymax = NULL, ylines = NULL, widths = 1, gap = NULL, reverse = NULL,
id = TRUE, horiz = FALSE)
{
getMaxPred <- function(x) {
mp <- max(x$prediction)
mpl <- ifelse(x$terminal, 0, getMaxPred(x$left))
mpr <- ifelse(x$terminal, 0, getMaxPred(x$right))
return(max(c(mp, mpl, mpr)))
}
y <- response(ctreeobj)[[1]]
if (is.factor(y) || class(y) == "was_ordered") {
ylevels <- levels(y)
if (is.null(beside))
beside <- if (length(ylevels) < 3)
FALSE
else TRUE
if (is.null(ymax))
ymax <- if (beside)
1.1
else 1
if (is.null(gap))
gap <- if (beside)
0.1
else 0
}
else {
if (is.null(beside))
beside <- FALSE
if (is.null(ymax))
ymax <- getMaxPred(ctreeobj@tree) * 1.1
ylevels <- seq(along = ctreeobj@tree$prediction)
if (length(ylevels) < 2)
ylevels <- ""
if (is.null(gap))
gap <- 1
}
if (is.null(reverse))
reverse <- !beside
if (is.null(fill))
fill <- gray.colors(length(ylevels))
if (is.null(ylines))
ylines <- if (beside)
c(3, 2)
else c(1.5, 2.5)
# My edit do not work if beside is not true
#################################################
if(!beside) horiz = FALSE
#################################################
rval <- function(node) {
pred <- node$prediction
if (reverse) {
pred <- rev(pred)
ylevels <- rev(ylevels)
}
np <- length(pred)
nc <- if (beside)
np
else 1
fill <- rep(fill, length.out = np)
widths <- rep(widths, length.out = nc)
col <- rep(col, length.out = nc)
ylines <- rep(ylines, length.out = 2)
gap <- gap * sum(widths)
#######################################################
if (!horiz){
yscale <- c(0, ymax)
xscale <- c(0, sum(widths) + (nc + 1) * gap)
} else {
xscale <- c(0, ymax)
yscale <- c(0, sum(widths) + (nc + 1) * gap)
}
#######################################################
top_vp <- viewport(layout = grid.layout(nrow = 2, ncol = 3,
widths = unit(c(ylines[1], 1, ylines[2]), c("lines",
"null", "lines")), heights = unit(c(1, 1), c("lines",
"null"))), width = unit(1, "npc"), height = unit(1,
"npc") - unit(2, "lines"), name = paste("node_barplot",
node$nodeID, sep = ""))
pushViewport(top_vp)
grid.rect(gp = gpar(fill = "white", col = 0))
top <- viewport(layout.pos.col = 2, layout.pos.row = 1)
pushViewport(top)
mainlab <- paste(ifelse(id, paste("Node", node$nodeID,
"(n = "), "n = "), sum(node$weights), ifelse(id,
")", ""), sep = "")
grid.text(mainlab)
popViewport()
plot <- viewport(layout.pos.col = 2, layout.pos.row = 2,
xscale = xscale, yscale = yscale, name = paste("node_barplot",
node$nodeID, "plot", sep = ""))
pushViewport(plot)
if (beside) {
#############################################################
if(!horiz){
xcenter <- cumsum(widths + gap) - widths/2
for (i in 1:np) {
grid.rect(x = xcenter[i], y = 0, height = pred[i],
width = widths[i], just = c("center", "bottom"),
default.units = "native", gp = gpar(col = col[i],
fill = fill[i]))
}
if (length(xcenter) > 1)
grid.xaxis(at = xcenter, label = FALSE)
grid.text(ylevels, x = xcenter, y = unit(-1, "lines"),
just = c("center", "top"), default.units = "native",
check.overlap = TRUE)
grid.yaxis()
} else {
ycenter <- cumsum(widths + gap) - widths/2
for (i in 1:np) {
grid.rect(y = ycenter[i], x = 0, width = pred[i],
height = widths[i], just = c("left", "center"),
default.units = "native", gp = gpar(col = col[i],
fill = fill[i]))
}
if (length(ycenter) > 1)
grid.yaxis(at = ycenter, label = FALSE)
grid.text(ylevels, y = ycenter, x = unit(-1, "lines"),
just = c("right", "center"), default.units = "native",
check.overlap = TRUE)
grid.xaxis()
}
#############################################################
}
else {
ycenter <- cumsum(pred) - pred
for (i in 1:np) {
grid.rect(x = xscale[2]/2, y = ycenter[i], height = min(pred[i],
ymax - ycenter[i]), width = widths[1], just = c("center",
"bottom"), default.units = "native", gp = gpar(col = col[i],
fill = fill[i]))
}
if (np > 1) {
grid.text(ylevels[1], x = unit(-1, "lines"),
y = 0, just = c("left", "center"), rot = 90,
default.units = "native", check.overlap = TRUE)
grid.text(ylevels[np], x = unit(-1, "lines"),
y = ymax, just = c("right", "center"), rot = 90,
default.units = "native", check.overlap = TRUE)
}
if (np > 2) {
grid.text(ylevels[-c(1, np)], x = unit(-1, "lines"),
y = ycenter[-c(1, np)], just = "center", rot = 90,
default.units = "native", check.overlap = TRUE)
}
grid.yaxis(main = FALSE)
}
grid.rect(gp = gpar(fill = "transparent"))
upViewport(2)
}
return(rval)
}
そして今、私たちはそれをテストすることができます!
plot(ctree, terminal_panel = alt_node_barplot(ctree, horiz = TRUE))
出力は次のとおりです。
ほんの数点:
私はこれがあなたの問題の解決策ではないかもしれないことを認めます。より簡単なオプションが存在しない場合、これはこのタイプの問題を解決するための方法にすぎません。
私が上で与えた機能を完全に信用しないでください。ご覧のとおり、trueを処理するコードのセクションを変更しなかったため、beside
パラメーターはパラメーターを自動的に無効にします(私の最初の編集)。この場合に機能させたい場合は、それらの編集を自分で行う必要があります。見て、開始してください。関数も壊れていると確信していますが、何もテストしていません。関数の元の作成者に少しお詫びを申し上げますが、これは単にデモンストレーションを目的としたものです。horiz
beside
?viewport
?grid.rect
reverse
これが少しお役に立てば幸いです。あなたがする必要があるさらなる編集で頑張ってください!