获取特定格式的规则表

时间:2015-01-05 15:27:44

标签: r

我设法从数据框中获取单变量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 =行,其中操作符<<=
    • 的值最小

但无法想象如何在R中轻松完成这项工作。

2 个答案:

答案 0 :(得分: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值。它输出另一个data.frame。然后,我们使用基本的split()命令将原始data.frame拆分为每个规则的一个,然后使用lapply在每个子集上执行rulecollapse,最后使用{{ 1}}将所有内容合并回一个data.frame。

答案 1 :(得分:1)

我的方法:

  • 将数据拆分为两组,一组用&gt;和&gt; =运算符,第二个使用&lt ;,&lt; =运算符
  • 按规则和数字对数据框进行排序(为&lt;,&lt; =和降序为&gt;,&gt; =)
  • 从排序数据框中获取每个规则的第一行
  • 完整外部联接数据框

代码:

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          <