2016-01-25 74 views
1

我是R的新手,我正在嘗試使用party:ctree庫的分類決策樹。一切似乎都很好。我得到了預期的結果和一個很好描述的情節。R中的閉包,函數內的函數調用,遞歸函數

現在,如果我想從摘要中提取結果,我會遍歷每個節點並提取信息。幸運的是,這已經寫入@baydoganm here。我想擴展此代碼並將結果寫入dataframe而不是打印它。

重複性代碼:

library(party) 
ct <- ctree(Species ~ ., data = iris) 

    traverse <- function(treenode){ 
     if(treenode$terminal){ 
      bas=paste(treenode$nodeID,treenode$prediction) 
     print(bas) #here the results are printed 
     return(0) 
       } 

traverse(treenode$left) 
traverse(treenode$right) 
    } 

traverse([email protected]) #function call 

這工作得很好,我得到的控制檯輸出。現在,如果我想將結果寫入數據框,則會遇到問題。

我到目前爲止的嘗試:試圖寫入使用可變閉包()的列表。但不知道如何讓它工作。

l <- list() 
count = 0 
traverse1 <- function(treenode,l){ 

if((treenode$terminal == T)){ 
    count <<- count + 1 
    print(count) 
    node = c(treenode$nodeID) 
    pred = c(treenode$prediction) 
    l[[count]] <- data.frame(node,pred) #write results in the dataframe  
    } 

    traverse1(treenode$left,l) 
    traverse1(treenode$right,l) 

} 
test <- traverse1([email protected],l)# function call 

我只得到我的最後一次通話的功能,其餘均爲無效

回答

2

智能方式的結果:使用assign()在全球環境下寫:

require(party) 
ct <- ctree(Species ~ ., data = iris) 

tt <- NULL 

traverse <- function(treenode){ 
    if(treenode$terminal){ 
    bas=paste(treenode$nodeID,treenode$prediction) 
    assign("tt", c(tt, bas), envir = .GlobalEnv) 
    print(bas) #here the results are printed 
    return(0) 
    } 

    traverse(treenode$left) 
    traverse(treenode$right) 
} 

traverse([email protected]) #function call 

data.frame(node.id = unlist(lapply(str_split(tt, " "), function(x) x[[1]])) 
     , prediction = unlist(lapply(str_split(tt, " "), function(x) x[[2]]))) 

骯髒的方式:使用sink()保存您的打印輸出。

sink(file = "test.csv", append = T) 
traverse([email protected]) #function call 
sink() 

tt <- read.csv("test.csv", header = F) 
+1

感謝。我從來沒有遇到過,設置globalEnv。今天學了點兒新東西。我也喜歡你的骯髒的方式+1它 – user3560220

2

如果使用來自partykit包中的新的改進ctree()實現,那麼這有你在fitted組件所需要的所有信息:

library("partykit") 
ct <- ctree(Species ~ ., data = iris) 
head(fitted(ct)) 
## (fitted) (weights) (response) 
## 1  2   1  setosa 
## 2  2   1  setosa 
## 3  2   1  setosa 
## 4  2   1  setosa 
## 5  2   1  setosa 
## 6  2   1  setosa 

因此,對於分類樹,你可以很容易地構造表使用xtabs()(或table())的絕對頻率響應。而對於迴歸樹,tapply()很容易被用來獲取手段,中位數等

在這種情況下,讓我們來看看在絕對和相對頻率以表格形式:

tab <- xtabs(~ `(fitted)` + `(response)`, data = fitted(ct)) 
tab 
##   (response) 
## (fitted) setosa versicolor virginica 
##  2  50   0   0 
##  5  0   45   1 
##  6  0   4   4 
##  7  0   1  45 
ptab <- prop.table(tab, 1) 
ptab 
##   (response) 
## (fitted)  setosa versicolor virginica 
##  2 1.00000000 0.00000000 0.00000000 
##  5 0.00000000 0.97826087 0.02173913 
##  6 0.00000000 0.50000000 0.50000000 
##  7 0.00000000 0.02173913 0.97826087 

一種替代途徑獲得頻率表tab應該是:table(predict(ct, type = "node"), iris$Species)

如果你想打開任何一個成一個數據幀的as.data.frame()作品就好了(可能加變量的一些重新貼標籤......):你快速回復

as.data.frame(ptab) 
## X.fitted. X.response.  Freq 
## 1   2  setosa 1.00000000 
## 2   5  setosa 0.00000000 
## 3   6  setosa 0.00000000 
## 4   7  setosa 0.00000000 
## 5   2 versicolor 0.00000000 
## 6   5 versicolor 0.97826087 
## 7   6 versicolor 0.50000000 
## 8   7 versicolor 0.02173913 
## 9   2 virginica 0.00000000 
## 10   5 virginica 0.02173913 
## 11   6 virginica 0.50000000 
## 12   7 virginica 0.97826087 
+0

這很奇怪你用partykit給我展示了什麼。我將在以後明確地使用它。現在我必須堅持'party'' – user3560220

+0

在'party'你可以這樣做:'tab < - table(where(ct),iris $ Species)'這會得到完全相同的結果作爲上面的例子。這應該比遍歷樹並將一些摘要寫入文本文件更容易。 –