2015-01-05 67 views
2

我設法在其中對於每個葉節點有規則數據幀從單可變rpart模型獲得輸出施加一路到行中的根節點:獲取規則表中特定格式

x <- read.table(header=T, sep="", stringsAsFactors = FALSE,text=" 
id number operator rule 
1  8.5  >= 4 
2 14.5  >= 4 
3  8.5  >= 10 
4 14.5  < 10 
5  9.5  < 10 
6  8.5  >= 22 
7 14.5  < 22 
8  9.5  >= 22 
9 12.5  >= 22 
10 8.5  >= 46 
11 14.5  < 46 
12 9.5  >= 46 
13 12.5  < 46 
14 11.5  < 46 
15 8.5  >= 47 
16 14.5  < 47 
17 9.5  >= 47 
18 12.5  < 47 
19 11.5  >= 47 
20 8.5  < 6 
21  4  < 6 
22 8.5  < 7 
23  4  >= 7 
") 

規則由rule標識(例如,具有rule==22的所有行構成一個規則)。現在,我想變換這樣的方式這個數據,我有按規則一行:

rule minOperator maxOperator minValue maxValue 
4 >=   NA   14.5  Inf 
10 >=   <   8.5  9.5 
22 >=   <   12.5  14.5 
46 >=   <   9.5  11.5 
47 >=   <   11.5  12.5 
6 NA   <   -Inf  4 
7 >=   <    4  8.5 

我看到的算法是這樣的:

  • 爲每個規則
    • minOperatorminValue =對於運營商有最大價值的行>>=
    • maxOperatormaxValue =有最小值的行對於運營商< imum價值或<=

,但找不出如何做到這一點很容易在R.

+1

是你的樣品結果按照您的描述準確嗎?您描述minOperator和minValue,以便我們查看子集(x,規則== 47和%c(「<」,「<=」))中的運算符%(對於規則47),但這些值分別爲14.5和12.5,但你的最小值爲11.5。你可以仔細檢查你的例子嗎? – MrFlick

+0

@MrFlick對不起,我在描述中轉換了兩邊。對於規則47和'minOperator',我們正在尋找最大值,其中運算符是'>'或'> =',這是11.5 –

回答

4

這是一個有點亂,但似乎這樣的伎倆

rulecollapse <- function(d, mins=c(">", ">="), maxs=c("<", "<=")) { 
    mn<-which(d$operator %in% mins)[which.max(d$number[d$operator %in% mins])] 
    mx<-which(d$operator %in% maxs)[which.min(d$number[d$operator %in% maxs])] 
    data.frame(list(rule=d$rule[1]), 
    if (length(mn)>0) { 
     list(minOperator=d$operator[mn], minValue=d$number[mn]) 
    } else { 
     list(minOperator=NA, minValue=-Inf) 
    }, 
    if (length(mx)>0) { 
     list(maxOperator=d$operator[mx], maxValue=d$number[mx]) 
    } else { 
     list(maxOperator=NA, maxValue=Inf) 
    } 
    ) 
} 

do.call(rbind, lapply(split(x, x$rule), rulecollapse))[, c(1,2,4,3,5)] 

它會產生

rule minOperator maxOperator minValue maxValue 
4  4   >=  <NA>  14.5  Inf 
6  6  <NA>   <  -Inf  4.0 
7  7   >=   <  4.0  8.5 
10 10   >=   <  8.5  9.5 
22 22   >=   <  12.5  14.5 
46 46   >=   <  9.5  11.5 
47 47   >=   <  11.5  12.5 

rulecollapse函數需要一個數據框和一個規則的所有行。然後它會根據您的描述查找最小/最大值,如果未找到,則返回NA/Inf值。它輸出另一個數據幀。然後,我們使用基本的split()命令將每個規則的原始數據幀拆分爲一個,然後使用lapply對這些子集中的每一個執行rulecollapse,最後使用do.call(rbind, ..)將所有內容合併到一個數據幀中。

+0

非常好。你是否介意提供至少簡短的解釋它是如何工作的?我找到了不同的解決方案,請參閱下面的答案 –

+0

@TomasGreif已添加簡要說明。 – MrFlick

1

我的方法:

  • 分割的數據爲兩個集合,一個具有>和> =運營​​商和第二與<,< =運營商
  • 分類數據通過規則和號碼(asceding爲<,<幀=降了>,> =)
  • 獲得第一行從排序的數據每幀規則
  • 全外連接的數據幀

代碼:在

minRules <- x[x$operator %in% c('>','>='),] 
maxRules <- x[x$operator %in% c('<','<='),] 

merge(
    aggregate(. ~ rule, data = minRules[with(minRules, order(rule, -number)), ], 
      FUN=head, 1), 
    aggregate(. ~ rule, data = maxRules[with(maxRules, order(rule, number)), ], 
      FUN=head, 1), 
    by = 'rule', all = TRUE 
) 

結果:

rule id.x number.x operator.x id.y number.y operator.y 
1 4 2  14.5   >= <NA>  <NA>  <NA> 
2 6 <NA>  <NA>  <NA> 21  4   < 
3 7 23  4   >= 22  8.5   < 
4 10 3  8.5   >= 5  9.5   < 
5 22 9  12.5   >= 7  14.5   < 
6 46 12  9.5   >= 14  11.5   < 
7 47 19  11.5   >= 18  12.5   <