-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathmap_cols.R
More file actions
97 lines (96 loc) · 3.46 KB
/
map_cols.R
File metadata and controls
97 lines (96 loc) · 3.46 KB
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
88
89
90
91
92
93
94
95
96
97
#' Remap values in a set of columns.
#'
#' @param source optree relop node or data.frame.
#' @param colmap data.frame with columns column_name, old_value, new_value.
#' @param ... force later arguments to bind by name.
#' @param null_default logical, if TRUE map non-matching values to NULL (else they map to self).
#' @return implementing optree or altered data.frame
#'
#' @examples
#'
#' if (requireNamespace("DBI", quietly = TRUE) && requireNamespace("RSQLite", quietly = TRUE)) {
#' my_db <- DBI::dbConnect(RSQLite::SQLite(),
#' ":memory:")
#'
#' d <- rq_copy_to(my_db, 'd',
#' data.frame(a = c("1", "2", "1", "3"),
#' b = c("1", "1", "3", "2"),
#' c = c("1", "2", "3", "4"),
#' stringsAsFactors = FALSE),
#' temporary = TRUE,
#' overwrite = TRUE)
#' mp <- build_frame(
#' "column_name", "old_value", "new_value" |
#' "a" , "1" , "10" |
#' "a" , "2" , "20" |
#' "b" , "1" , "100" |
#' "b" , "3" , "300" )
#'
#' # example
#' op_tree <- d %.>%
#' map_column_values(., mp)
#' cat(format(op_tree))
#' sql <- to_sql(op_tree, my_db)
#' cat(sql)
#' print(DBI::dbGetQuery(my_db, sql))
#'
#' # cleanup
#' DBI::dbDisconnect(my_db)
#' }
#'
#' @export
#'
map_column_values <- function(source, colmap,
...,
null_default = FALSE) {
wrapr::stop_if_dot_args(substitute(list(...)),
"rquery::map_column_values")
colmap_name <- rquery_deparse(substitute(colmap))
control_cols <- c("column_name", "old_value", "new_value")
missing <- setdiff(control_cols, colnames(colmap))
if(length(missing)>0) {
stop(paste("rquery::map_column_value colmap missing column(s):",
paste(missing, collapse = ", ")))
}
for(ci in control_cols) {
if(is.factor(colmap[[ci]])) {
colmap[[ci]] <- as.character(ci)
}
}
cols <- column_names(source)
targets <- intersect(cols,
sort(unique(colmap$column_name)))
if(length(targets)<=0) {
return(source)
}
terms <- lapply(targets,
function(ci) {
default <- "NULL"
if(!null_default) {
default <- as.name(ci)
}
cmpi <- colmap[colmap$column_name == ci, , drop = FALSE]
ni <- nrow(cmpi)
ti <- lapply(seq_len(ni),
function(j) {
tij <- list("WHEN ",
as.name(ci),
" = ",
list(cmpi$old_value[[j]]),
" THEN ",
list(cmpi$new_value[[j]]))
})
ti <- unlist(ti, recursive = FALSE)
c(list("CASE "), ti, list(" ELSE "), default, " END")
}
)
names(terms) <- targets
nd <- sql_node(source, terms,
orig_columns = TRUE)
if("relop" %in% class(nd)) {
nd$display_form <- paste0("map_column_values(., ",
colmap_name,
")")
}
nd
}