首页 > 解决方案 > 在函数中创建循环,以便 URL 返回数据框

问题描述

我得到了一个标识符列表(在这种情况下,标识符称为 NPI)。这些标识符可以复制并粘贴到本网站 ( https://npiregistry.cms.hhs.gov/registry/ ?)。我想返回 NPI 编号的名称、医生姓名、地址、电话号码和专业。

我有超过 3,000 个标识符,因此复制和粘贴效率不高,并且不容易重复以供将来使用。

如果可能,我想创建一个 URL 列表,将它们传递给一个函数,并接收一个数据框,该数据框为我提供上述变量(NPI、NAME、ADDRESS、PHONE、SPECIALTY)。

我能够编写一个生成所需 URL 的函数:

以下是一些供参考的 NPI 编号:1417024746、1386790517、1518101096、1255500625。

这是我用于读取包含我的 NPI 的文件的代码

npiList <- c("1417024746", "1386790517", "1518101096", "1255500625")
npiList <- as.list(npiList)
npiList <- unlist(npiList, use.names = FALSE)

这是返回 URL 列表的函数:

npiaddress <- function(x){
url <- paste("https://npiregistry.cms.hhs.gov/registry/search-results- 
table?number=",x,"&addressType=ANY", sep = "")
return(url)
}

我将列表保存到一个变量中,也许这是我的失败:

npi_urls <- npiaddress(npiList)

从这里我编写了一个可以接受单个 URL 的函数,检索我想要的数据并将其转换为数据框。我的问题是我不能传递多个 URL:

npiLookup <- function (x){
url <- x
webpage <- read_html(url)
npi_html <- html_nodes(webpage, "td")
npi <- html_text(npi_html)
npi[4] <- gsub("\r?\n|\r", " ", npi[4])
npi[4] <- gsub("\r?\t|\r", " ", npi[4])
npiFinal <- npi[c(1:2,4:6)]
npiFinal <- as.data.frame(npiFinal)
npiFinal <- t(npiFinal)
npiFinal <- as.data.frame(npiFinal)
names(npiFinal) <- c("NPI", "NAME", "ADDRESS", "PHONE", "SPECIALTY")
return(npiFinal)
}

例如:

如果我想获得以下标识符(1417024746)的数据框,我可以运行它并且它可以工作:

x <- npiLookup("https://npiregistry.cms.hhs.gov/registry/search-results-table?number=1417024746&addressType=ANY")
View(x)

我的示例输出根据需要返回 NPI、NAME、ADDRESS、PHONE、SPECIALTY,但同样,我需要为数千个 NPI 标识符执行此操作。我觉得我需要在 npiLookup 中进行循环。我也尝试将 npi_urls 放入 npiLookup 函数中,但它不起作用。

感谢您的帮助和花时间阅读。

标签: functionloopsweb-scraping

解决方案


你大部分都在那儿。最后一步使用这个有用的 R 成语:

do.call(rbind,lapply(npiList,function(npi) {url=npiaddress(npi); npiLookup(url)}))

do.call是一个基本 R 函数,它将函数(在本例中rbind)应用于由 . 生成的列表lapply。该列表是在您为每个元素npiLookup生成的 url 上运行函数的结果。npiaddressnpiList

如果其他人遇到此问题,请进一步评论以供将来参考:(1)我不知道您为什么要在开头使用as.list,序列;unlist这是多余的,可能是不必要的。(2) NPI 注册中心提供了一个编程接口 (API),避免了从 HTML 页面抓取数据的需要;从长远来看,这可能会更加稳健。(3) NPI 注册表以可下载文件的形式提供整个数据集;这可能是一种更简单的方法。


推荐阅读