2017-05-04 96 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