修正purrr包possibly函数 空tibble场景下返回NA值数据框
核心原因
purrr::possibly() 仅在原函数抛出显性运行错误时才会触发otherwise兜底逻辑。你的原函数返回0行空tibble属于正常执行完成的合法返回值,全程没有触发任何错误,因此封装后的函数不会走兜底分支,自然达不到预期效果。
调整方案
方案1:直接在原函数内增加空结果判断(最简便)
在原函数返回结果前增加行数判断,当结果为空时直接返回填充了NA的兜底tibble即可,不需要额外依赖possibly:
processCardPackMinimalRealtorInfo = function(rowPosition){ # collect realtor information realEstateInformation = bind_cols( realEstateCompanyName = CardPackMinimal[rowPosition] %>% html_elements('.re-CardPromotionLogo') %>% html_nodes("a") %>% html_children() %>% html_attr("title"), realEstatePageLink = CardPackMinimal[rowPosition] %>% html_elements('.re-CardPromotionLogo') %>% html_nodes("a") %>% html_attr('href') %>% paste("https://www.fotocasa.es", ., sep = "") ) # 空结果兜底判断 if (nrow(realEstateInformation) == 0) { return(tibble( realEstateCompanyName = NA_character_, realEstatePageLink = NA_character_ )) } return(realEstateInformation) }
方案2:编写通用包装器(不修改原函数)
如果不想改动原函数逻辑,可以自定义一个专门处理空tibble返回值的包装器,同时还可以和possibly嵌套使用,同时覆盖「运行报错」和「返回空结果」两类异常场景:
# 定义空tibble兜底包装器 empty_tibble_safely = function(target_func, fallback_value) { function(...) { result = target_func(...) # 识别0行数据框并返回兜底值 if (is.data.frame(result) && nrow(result) == 0) { return(fallback_value) } result } } # 先套possibly捕获显性错误,再套空值兜底 safeProcessCardPackMinimalRealtorInfo = processCardPackMinimalRealtorInfo %>% possibly( otherwise = tibble( realEstateCompanyName = NA_character_, realEstatePageLink = NA_character_ ) ) %>% empty_tibble_safely( fallback_value = tibble( realEstateCompanyName = NA_character_, realEstatePageLink = NA_character_ ) )
补充说明:如果爬取逻辑中还可能出现列数不匹配、网络请求失败等其他异常,嵌套使用两种包装器的方式可以一次性覆盖所有需要返回NA兜底的场景,不需要在原函数里写大量分支判断。
内容的提问来源于stack exchange,提问作者user113156
相关产品推荐
相关产品推荐

