获取特定格式的规则 table
Get rules table in specific format
我设法从数据框中的单个变量 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
我看到算法是这样的:
- 对于每条规则
minOperator
和 minValue
= 运算符 >
或 >=
有最大值的行
maxOperator
和 maxValue
= 运算符 <
或 <=
具有最小值的行
但不知道如何在 R 中轻松地做到这一点。
这有点乱,但似乎可以解决问题
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
函数需要一个包含单个规则所有行的数据框。然后根据您的描述查找 min/max 值,如果未找到,则 returns NA/Inf 值。它输出另一个 data.frame。然后我们使用基本的 split()
命令将你原来的 data.frame 分解为每个规则,然后使用 lapply
对每个子集执行 rulecollapse
,最后使用do.call(rbind, ..)
将所有内容合并回一个 data.frame。
我的做法:
- 将数据分成两组,一组使用 > 和 >= 运算符,第二组使用 <, <= 运算符
- 按规则和编号对数据帧进行排序(<、<= 升序,>、>= 降序)
- 从已排序的数据框中获取每个规则的第一行
- 完整的外连接数据帧
代码:
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 <
我设法从数据框中的单个变量 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
我看到算法是这样的:
- 对于每条规则
minOperator
和minValue
= 运算符>
或>=
有最大值的行
maxOperator
和maxValue
= 运算符<
或<=
具有最小值的行
但不知道如何在 R 中轻松地做到这一点。
这有点乱,但似乎可以解决问题
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
函数需要一个包含单个规则所有行的数据框。然后根据您的描述查找 min/max 值,如果未找到,则 returns NA/Inf 值。它输出另一个 data.frame。然后我们使用基本的 split()
命令将你原来的 data.frame 分解为每个规则,然后使用 lapply
对每个子集执行 rulecollapse
,最后使用do.call(rbind, ..)
将所有内容合并回一个 data.frame。
我的做法:
- 将数据分成两组,一组使用 > 和 >= 运算符,第二组使用 <, <= 运算符
- 按规则和编号对数据帧进行排序(<、<= 升序,>、>= 降序)
- 从已排序的数据框中获取每个规则的第一行
- 完整的外连接数据帧
代码:
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 <