tidyjson代码中的变量名

我想在函数中为tidyjson包编写代码,如下所示:

> enter_object(object) %>%    spread_values(
>     varnames[1] = jstring(strings[1]),
>     varnames[2] = jstring(strings[2]),
>     varnames[3] = jstring(strings[3])   )

如果我有一个像foo而不是varnames [1]的文字字符串,这段代码运行正常.但我希望函数更灵活,这样我就可以生成大量的varnames,而不是手工编写.变量名最终作为数据框列的名称.随着我目前的失败,我得到:

+         enter_object(object) %>% 
+         spread_values(
+           varnames[[1]] = jstring(strings[1]),
Error: unexpected '=' in:
"        spread_values(
          varnames[[1]] ="
>           varnames[2] = jstring(strings[2]),
Error: unexpected ',' in "          varnames[2] = jstring(strings[2]),"
>           varnames[3] = jstring(strings[3])
Error in prep_path(...) : object 'strings' not found
>         ) 
Error: unexpected ')' in "        )"

我无法弄清楚在=之前放置什么样的对象,以便识别出=.

以下是使用MrFlick解决方案的玩具示例:

> sample_json <- '[
+     {
+         "id": 10097652,
+         "members": 2386,
+         "category": {
+             "id": 23,
+             "name": "Outdoors & Adventure",
+             "shortname": "Outdoors"
+         }   
+   }
+ ]'
> 
> group_category1 <- sample_json %>%  as.tbl_json %>% 
+     gather_array %>%  #gather_keys %>% 
+     spread_values(
+       group_id = jstring("id")
+   ) %>%
+       enter_object("category") %>% 
+       spread_values(
+         category_id = jstring("id"),
+         category_name = jstring("name"),
+         category_short_name = jstring("shortname")
+       ) 
> head(group_category1)
  document.id array.index group_id category_id        category_name category_short_name
1           1           1 10097652          23 Outdoors & Adventure            Outdoors
> 
> my_spread_values <- function(x, names, values) { 
+     stopifnot(length(names) == length(values))
+     do.call("spread_values", c(list(x), setNames(as.list(values), names )))
+  } 
> varnames <-  c("category_id", "category_name", "category_shortname")
> strings <-  c("id", "name", "shortname")
> 
> group_category2 <- sample_json %>%  as.tbl_json %>% 
+   gather_array %>% 
+   spread_values(group_id = jstring("id")) %>% 
+ enter_object("category") %>% my_spread_values( 
+     varnames, list(jstring(strings[1]), jstring(strings[2]), jstring(strings[3]) ) )
> head(group_category2)
  document.id array.index group_id category_id        category_name category_shortname
1           1           1 10097652          23 Outdoors & Adventure           Outdoors
> 

这完美地运作! (一旦我犯过一些粗心的错误就修好了!)

最佳答案 通常,R不允许您使用R变量动态指定参数名称.您必须使用do.call动态构建实际调用,但这不适用于%>%管道语法.我们可以创建一个更具动态性的替代版本的函数

my_spread_values <- function(x, names, values) {
    stopifnot(length(names)==length(values))
    do.call("spread_values", c(list(x), setNames(as.list(values), names)))
}

然后你可以这样称呼它

enter_object(object) %>% my_spread_values(
    varnames, 
    list(jstring(strings[1]),jstring(strings[2]),jstring(strings[3]))
)

或者,如果您总是使用简单的jstring扩展字符串

enter_object(object) %>% my_spread_values(
    varnames, 
    lapply(strings, jstring)
)
点赞