首先,很抱歉,这是一篇很长的文章-内容很详尽,我想要实现的结果与我已经能够实现的结果之间的差异是微妙而重要的。
核心问题是我想在R中创建一个递归列表,其中列表元素向上递增。
核心原因是,现在我正尝试编写脚本以通过GTM API在Google跟踪代码管理器中自动创建查找表变量。
用于创建变量的文档在这里:https://developers.google.com/tag-manager/api/v2/reference/accounts/containers/workspaces/variables/create
所需的工作流程是这样:
googlesheets
包从Google表格中提取映射表我目前遇到的问题是步骤2,以正确的方式创建列表。我想出了一种对GTM API提供的列表进行反向工程的方法,但是该方法涉及手动将值中的每一行添加到要映射为新列表的位置,当行长可变时(除了屁股疼痛)。
这是工作最终结果的外观(这是通过手动方法完成的);这称为post_body1
:
$name
[1] "test1"
$type
[1] "smm"
$parameter
$parameter[[1]]
$parameter[[1]]$type
[1] "boolean"
$parameter[[1]]$key
[1] "setDefaultValue"
$parameter[[1]]$value
[1] "true"
$parameter[[2]]
$parameter[[2]]$type
[1] "template"
$parameter[[2]]$key
[1] "input"
$parameter[[2]]$value
[1] "{{Event Name}}"
$parameter[[3]]
$parameter[[3]]$type
[1] "list"
$parameter[[3]]$key
[1] "map"
$parameter[[3]]$list
$parameter[[3]]$list[[1]]
$parameter[[3]]$list[[1]]$type
[1] "map"
$parameter[[3]]$list[[1]]$map
$parameter[[3]]$list[[1]]$map[[1]]
$parameter[[3]]$list[[1]]$map[[1]]$type
[1] "template"
$parameter[[3]]$list[[1]]$map[[1]]$key
[1] "key"
$parameter[[3]]$list[[1]]$map[[1]]$value
[1] "explosion"
$parameter[[3]]$list[[1]]$map[[2]]
$parameter[[3]]$list[[1]]$map[[2]]$type
[1] "template"
$parameter[[3]]$list[[1]]$map[[2]]$key
[1] "value"
$parameter[[3]]$list[[1]]$map[[2]]$value
[1] "volcano"
$parameter[[3]]$list[[2]]
$parameter[[3]]$list[[2]]$type
[1] "map"
$parameter[[3]]$list[[2]]$map
$parameter[[3]]$list[[2]]$map[[1]]
$parameter[[3]]$list[[2]]$map[[1]]$type
[1] "template"
$parameter[[3]]$list[[2]]$map[[1]]$key
[1] "key"
$parameter[[3]]$list[[2]]$map[[1]]$value
[1] "flood"
$parameter[[3]]$list[[2]]$map[[2]]
$parameter[[3]]$list[[2]]$map[[2]]$type
[1] "template"
$parameter[[3]]$list[[2]]$map[[2]]$key
[1] "value"
$parameter[[3]]$list[[2]]$map[[2]]$value
[1] "tsunami"
$parameter[[3]]$list[[3]]
$parameter[[3]]$list[[3]]$type
[1] "map"
$parameter[[3]]$list[[3]]$map
$parameter[[3]]$list[[3]]$map[[1]]
$parameter[[3]]$list[[3]]$map[[1]]$type
[1] "template"
$parameter[[3]]$list[[3]]$map[[1]]$key
[1] "key"
$parameter[[3]]$list[[3]]$map[[1]]$value
[1] "drought"
$parameter[[3]]$list[[3]]$map[[2]]
$parameter[[3]]$list[[3]]$map[[2]]$type
[1] "template"
$parameter[[3]]$list[[3]]$map[[2]]$key
[1] "value"
$parameter[[3]]$list[[3]]$map[[2]]$value
[1] "heatwave"
以下是一些变量:
variable_name <- 'test1'
map_values <- tibble(key=c('explosion','flood','drought'),
value = c('volcano','tsunami','heatwave'))
var_code <- 'smm'
set_default <- TRUE
map_input <- 'Event Name'
这是用于创建上述列表的代码-如上所述,这不是可扩展的解决方案。
post_body1 <- list(name = variable_name,
type = var_code,
parameter = list(
list(type = 'boolean',
key = 'setDefaultValue',
value = ifelse(set_default == TRUE,'true','false')),
list(type = 'template',
key = 'input',
value = paste('{{',map_input,'}}',sep='')),
list(type = 'list',
key = 'map',
list = list(list(
type = 'map',
map = list(list(
type = 'template',
key = 'key',
value = map_values$key[[1]]),
list(type = 'template',
key = 'value',
value = map_values$value[[1]])
)
),
list(type = 'map',
map = list(list(
type = 'template',
key = 'key',
value = map_values$key[[2]]),
list(type = 'template',
key = 'value',
value = map_values$value[[2]])
)
),
list(type = 'map',
map = list(list(
type = 'template',
key = 'key',
value = map_values$key[[3]]),
list(type = 'template',
key = 'value',
value = map_values$value[[3]])
)
)
)
)
)
)
因此,我试图创建一个新的解决方案,以编程方式处理post_body1$parameter[[3]]$list
的创建,并且我已经几乎完成了但还不够,而且我认为这不是一个非常优雅的解决方案,并且有一种使用purrr
包之类的东西创建它的更好方法。
test_list <- list()
for (i in 1:nrow(map_values)) {
newlist <- list(
type = 'map',
map = list(list(
type = 'template',
key = 'key',
value = map_values$key[[i]]),
list(type = 'template',
key = 'value',
value = map_values$value[[i]])
)
)
test_list <- c(test_list,newlist)
}
post_body2 <- list(name = variable_name,
type = var_code,
parameter = list(
list(type = 'boolean',
key = 'setDefaultValue',
value = ifelse(set_default == TRUE,'true','false')),
list(type = 'template',
key = 'input',
value = paste('{{',map_input,'}}',sep='')),
list(type = 'list',
key = 'map',
list = list(test_list))
)
)
因此,此方法产生的结果与上述蛮力方法非常相似,但有一个关键区别:post_body2$parameter[[3]]$list
的索引的递增方式与post_body1$parameter[[3]]$list
的递增方式不同; post_body2$parameter[[3]]$list
如下所示:
$parameter[[3]]$list
$parameter[[3]]$list[[1]]
$parameter[[3]]$list[[1]]$type
[1] "map"
$parameter[[3]]$list[[1]]$map
$parameter[[3]]$list[[1]]$map[[1]]
$parameter[[3]]$list[[1]]$map[[1]]$type
[1] "template"
$parameter[[3]]$list[[1]]$map[[1]]$key
[1] "key"
$parameter[[3]]$list[[1]]$map[[1]]$value
[1] "explosion"
$parameter[[3]]$list[[1]]$map[[2]]
$parameter[[3]]$list[[1]]$map[[2]]$type
[1] "template"
$parameter[[3]]$list[[1]]$map[[2]]$key
[1] "value"
$parameter[[3]]$list[[1]]$map[[2]]$value
[1] "volcano"
$parameter[[3]]$list[[1]]$type
[1] "map"
$parameter[[3]]$list[[1]]$map
$parameter[[3]]$list[[1]]$map[[1]]
$parameter[[3]]$list[[1]]$map[[1]]$type
[1] "template"
$parameter[[3]]$list[[1]]$map[[1]]$key
[1] "key"
$parameter[[3]]$list[[1]]$map[[1]]$value
[1] "flood"
$parameter[[3]]$list[[1]]$map[[2]]
$parameter[[3]]$list[[1]]$map[[2]]$type
[1] "template"
$parameter[[3]]$list[[1]]$map[[2]]$key
[1] "value"
$parameter[[3]]$list[[1]]$map[[2]]$value
[1] "tsunami"
$parameter[[3]]$list[[1]]$type
[1] "map"
$parameter[[3]]$list[[1]]$map
$parameter[[3]]$list[[1]]$map[[1]]
$parameter[[3]]$list[[1]]$map[[1]]$type
[1] "template"
$parameter[[3]]$list[[1]]$map[[1]]$key
[1] "key"
$parameter[[3]]$list[[1]]$map[[1]]$value
[1] "drought"
$parameter[[3]]$list[[1]]$map[[2]]
$parameter[[3]]$list[[1]]$map[[2]]$type
[1] "template"
$parameter[[3]]$list[[1]]$map[[2]]$key
[1] "value"
$parameter[[3]]$list[[1]]$map[[2]]$value
[1] "heatwave"
如果您仍在阅读,我可以用什么方法以所需格式创建此列表?
编辑:根据@ muddy-cloudskipper的请求,我正在为所需的输出添加dput
,这是
list(name = "test1", type = "smm", parameter = list(list(type = "boolean",
key = "setDefaultValue", value = "true"), list(type = "template",
key = "input", value = "{{Event Name}}"), list(type = "list",
key = "map", list = list(list(type = "map", map = list(list(
type = "template", key = "key", value = "explosion"),
list(type = "template", key = "value", value = "volcano"))),
list(type = "map", map = list(list(type = "template",
key = "key", value = "flood"), list(type = "template",
key = "value", value = "tsunami"))), list(type = "map",
map = list(list(type = "template", key = "key", value = "drought"),
list(type = "template", key = "value", value = "heatwave")))))))
我要创建的是一个将导致输出的函数;可能会是这样,尽管这不太正确。
function (variable_name, var_code, set_default, map_input, map_values)
{
test_list <- list()
for (i in 1:nrow(map_values)) {
newlist <- list(type = "map", map = list(list(type = "template",
key = "key", value = map_values$key[[i]]), list(type = "template",
key = "value", value = map_values$value[[i]])))
test_list <- c(test_list, newlist)
}
post_body <- list(name = variable_name, type = var_code,
parameter = list(list(type = "boolean", key = "setDefaultValue",
value = ifelse(set_default == TRUE, "true", "false")),
list(type = "template", key = "input", value = paste("{{",
map_input, "}}", sep = "")), list(type = "list",
key = "map", list = list(test_list))))
return(post_body)
}
答案 0 :(得分:1)
我认为这应该起作用,我分别构建列表的可变部分,然后将所有内容粘在一起:
sublist <- unname(Map(function(key,value) list(type = "map",
map=list(
list(type="template",
key ="key",
value = key),
list(type = "template",
key = "value",
value = value))), map_values$key, map_values$value))
res <- list(name = variable_name,
type = var_code,
parameter = c(list(
list(type = 'boolean',
key = 'setDefaultValue',
value = ifelse(set_default == TRUE,'true','false')),
list(type = 'template',
key = 'input',
value = paste('{{',map_input,'}}',sep=''))),
list(list(type = "list",
key = "map",
list=sublist))))
identical(res,output)
# [1] TRUE