2017-05-04 82 views
4

我试图在R中使用tidyverse/dplyr包来处理数据,包括向在线API(从Altmetric)矢量化调用以使用mutate添加行。在R中使用dplyr/mutate修复不兼容类型错误

我可以创建的最小代码重现错误是下面的代码。我得到的错误“错误:不兼容的类型,期待一个数字矢量”

library(tidyverse) 
library(jsonlite) 

fromJSON_wrapper <- function(x,y) { 
    fromJSON(x)[[c(y)]] 
} 

toy <- tibble(
     doi = c("10.1002/anie.201500251", "10.1080/19443994.2015.1005695", "10.1007/s13721-015-0095-0"), 
     url = c("https://api.altmetric.com/v1/doi/10.1002/anie.201500251", "https://api.altmetric.com/v1/doi/10.1080/19443994.2015.1005695", "https://api.altmetric.com/v1/doi/10.1080/19443994.2015.1005695") 
    ) 

extracted <- toy %>% rowwise() %>% mutate(score = fromJSON_wrapper(url,"score")) 

提取下方作品单节比分,是否只是使用包装上或在一排tibble,我不知道为什么代码我的代码不起作用。

fromJSON_wrapper("https://api.altmetric.com/v1/doi/10.1007/s13721-015-0095-0") 
extracted <- toy[1,] %>% rowwise() %>% mutate(score = fromJSON_wrapper(url, "score")) 

任何建议,将不胜感激。

+1

使用'as.numeric(fromJSON(x)的[[C(Y)]])'会工作。问题是有时函数返回一个数值,而其他时间返回一个整数。它似乎不像'dplyr'喜欢把它们合并成一个数字列。 – MrFlick

回答

3

只需遍历URL矢量并提取所需内容就简单多了。 purrr::map_dbl使这个很简单,但sapply也可以正常工作。

library(tidyverse) 

toy <- tibble(
    doi = c("10.1002/anie.201500251", "10.1080/19443994.2015.1005695", "10.1007/s13721-015-0095-0"), 
    url = c("https://api.altmetric.com/v1/doi/10.1002/anie.201500251", "https://api.altmetric.com/v1/doi/10.1080/19443994.2015.1005695", "https://api.altmetric.com/v1/doi/10.1080/19443994.2015.1005695") 
) 

extracted <- toy %>% mutate(score = map_dbl(url, ~jsonlite::fromJSON(.x)$score)) 

extracted %>% select(doi, score) 
#> # A tibble: 3 × 2 
#>        doi score 
#>       <chr> <dbl> 
#> 1  10.1002/anie.201500251 0.25 
#> 2 10.1080/19443994.2015.1005695 1.00 
#> 3  10.1007/s13721-015-0095-0 1.00 
+0

感谢alistaire,我知道应该有一个简单的方法来做到这一点! –

+0

我想知道是否有一种简单的方法可以获取fromJSON返回的所有数据,并根据列表中的名称将其平铺到数据框中的一系列列中。例如:list_df <- toy %>%mutate(json_data = map(url,〜jsonlite :: fromJSON(.x)))后面跟着df2 < - data.frame(matrix(unlist(list_df $ json_data),nrow = 3,byrow = T ),stringsAsFactors = F)(这个代码不起作用,因为json_data的每一行都有一个可变长度,并且有一个不同的命名元素的子集 –

+0

你可以用'玩具<- toy %>%mutate简化抓取它(json_data = map(url, jsonlite :: fromJSON))'并且随意提取碎片,但是如果响应没有标准化并且长度不同,那么就没有一个明显的data.frame结构来转换整个事物。 %mutate(json_df = map(json_data,〜.x%>%map(list)%>%as_data_frame))%>%unnest(json_df)'',但最终会出现很多杂乱的列表列。 – alistaire