-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path4_spa.R
87 lines (68 loc) · 2.11 KB
/
4_spa.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# Load data.table for df_ification
library(data.table)
# Get p for a given country and item
get_pos <- function(idx, country, item) {
which(idx$country == country & idx$item == item)
}
# Recursively split alpha (x[p]), given a split defined by D[p, ].
# Calculate for values >= epsilon and go through lvl_cap layers.
get_path <- function(alpha, D, p, epsilon, lvl_cap = 3, lvl = 0) {
tmp <- alpha * D[p, ]
out <- tmp[tmp >= epsilon]
rest <- sum(tmp[tmp < epsilon])
if(lvl >= lvl_cap) {return(list(lvl = lvl, split = c(out, "rest" = rest)))}
lvl <- lvl + 1
return(
list(
lvl = lvl - 1,
split = c(out, "rest" = rest),
down = lapply(structure(names(out), names = names(out)),
function(x, D, out, epsilon, lvl_cap, lvl) {
get_path(out[[x]], D,
p = as.integer(substr(x, 4, nchar(x))),
epsilon, lvl_cap, lvl)
}, out, D, epsilon, lvl_cap, lvl))
)
}
epsilon <- 1e-3
lvl_cap <- 3
country <- "BRA"
item <- "Cattle"
x <- c(0.5, 1)
D <- matrix(c(0.4, 0.8, 0.6, 0.2), nrow = 2,
dimnames = list(c("row1", "row2"), c("col1", "col2")))
# p <- get_pos(index, country, item)
p <- 1
alpha <- x[p]
tree <- get_path(alpha, D, p, epsilon, lvl_cap)
# tree
# Transform a tree-list into a data.table with level, id-path and value
df_ify <- function(x, prev = "") {
if(is.null(x$down)) {
data.table("lvl" = x[[1]],
id = paste0(prev, names(x[[2]])),
val = x[[2]])
} else {
rbindlist(
list(
data.table("lvl" = x[[1]],
id = paste0(prev, names(x[[2]])),
val = x[[2]]),
rbindlist(
lapply(names(x[["down"]]), function(name, x, prev) {
df_ify(x[["down"]][[name]], prev = paste0(name, " > ", prev))
}, x, prev)
)
)
)
}
}
df <- df_ify(tree)
# df
# Transform df to include levels in separate columns
split <- strsplit(df$id, " > ")
for(i in 0:lvl_cap) {
df[[paste0("l_", i)]] <- sapply(split, function(x, i) x[i], i = i + 1)
}
df$id <- NULL
# df