在函数中创建循环,以便URL返回数据框

时间:2019-05-14 14:53:53

标签: function loops web-scraping

为我提供了一个标识符列表(在这种情况下,该标识符称为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函数中,但是它不起作用。

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

1 个答案:

答案 0 :(得分:0)

您已到达那里。最后一步使用了这个有用的R习惯用法:

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

do.call是基本R函数,它将函数(在这种情况下为rbind)应用于lapply生成的列表。该列表是在npiLookupnpiaddress的每个元素生成的URL上运行npiList函数的结果。

如果有其他人遇到此问题,请进一步评论,以供将来参考:(1)我不知道您为什么一开始就按as.listunlist顺序进行操作;这是多余的,可能不必要。 (2)NPI注册表提供了一个编程接口(API),避免了从HTML页面抓取数据的麻烦;从长远来看,这可能会更强大。 (3)NPI注册中心将整个数据集作为可下载文件提供;这可能是更简单的方法。