r - 拆分没有分隔符和不均匀长度的值
问题描述
我从以下站点抓取了第二个 HTML 表
下面是我提取表格的代码:
FLlist <- read_html("http://www.floridahealth.gov/programs-and-
services/office-of-medical-marijuana-use/medical-marijuana-treatment-
centers/index.html")
FLDispensaries <- as.data.frame(FLlist %>%
html_nodes("table") %>%
.[[2]] %>%
html_table(header = TRUE))
write.csv(FLtest, "FLTest.csv")
该表在 Excel 中填充,如下所示:List after iswritten as a CSV
我想分隔地址信息,但长度或分隔符没有一致性。这个列表将继续增长,我在其他数据集上遇到了同样的问题,所以我想编写一个代码来自动化分离地址数据的过程。也许我一开始就可以在刮桌子的时候做到这一点?
解决方案
由于您尚未指定要如何分隔地址,因此我假设地址块中的每一行都应转到单独的列。
为此,您可以使用足够的 XPath 查询选择第二个表的 p-tags,例如
//*[@id="DispensingFacilities"]/tbody/tr/td/p/text()
然后遍历结果并从头开始创建表结构。以这种方式生成 CSV 现在有点复杂。有几种方法,如下图所示:
library(xml2)
library(magrittr)
library(rvest)
FLlist <- read_html("http://www.floridahealth.gov/programs-and-services/office-of-medical-marijuana-use/medical-marijuana-treatment-centers/index.html")
FLDispensaries <- as.data.frame(FLlist %>%
html_nodes("table") %>%
.[[2]] %>%
html_table(header = TRUE))
FLTable <- html_nodes(x=FLlist, xpath='//*[@id="DispensingFacilities"]/tbody/tr/td/p/text()')
#helper
trim <- function (x) gsub("^\\s+|\\s+$", "", x)
mat<-matrix(list(), ncol=4)
li <- c()
row <- 0;
col <- 1;
for(i in FLTable){
li <- c(li,trim(html_text(i)));
if(col %% 4 == 0) {
row <- row + 1;
mat[[row]] <- li;
li <- c();
}
col <- col + 1;
}
#to matrix/list to dataframe
library(plyr)
mat.df <- as.data.frame(do.call(rbind, mat))
write.csv(mat.df, "FLTest.csv")
由于您只想拥有实际地址,因此我将 XPath 更改为仅从第二个td
开始选择第二个tr
FLTable <- html_nodes(x=FLlist, xpath='//*[@id="DispensingFacilities"]/tbody/tr[position()>1]/td[2]/p')
li <- c()
row <- 1;
mat<-matrix(list(), ncol=2)
for (i in seq_along(FLTable)) {
addrlines <- str_split(xml_text(FLTable[[i]]), "\\s\\s")
for (a in seq_along(addrlines[[1]])) {
if(a %% 2 == 0) {
li <- c(li,paste(addrlines[[1]][a], addrlines[[1]][a+1]));
mat[[row]] <- li;
li <- c();
row <- row + 1;
} else if(a %% 3 == 0) {
next; #skip
} else {
li <- c(li,addrlines[[1]][a]);
}
}
}
并创建一个不错的输出
outputFile <- "output.csv"
#to matrix/list to dataframe
mat.df <- as.data.frame(do.call(rbind, mat))
cat(c("No.,", "Name,", "Address"), '\n', file = outputFile)
write.table(mat.df,outputFile,sep=',',append = T, col.names = F)
生成的 CSV 如下所示:
No., Name, Address
"1","AltMed Florida (MuV)","5909 U.S. Hwy 41 N Apollo Beach, FL 33572"
"2","Trulieve","1103 14th Street West Bradenton, FL 34205"
...
"55","Trulieve","1814 Commerce Avenue Vero Beach, FL 32960"
推荐阅读
- codenameone - 如何为 PickerComponent 添加 ActionListener 或 DataChangedListener
- json - Django d3.js 加载 JSON 数据
- java - 使用 Lombok Builder 注入构造函数依赖项
- graphql - Next.js 应用程序中的 React-Apollo 身份验证
- css - Bootstrap 4 边框重叠按钮元素
- python - 在“with”关键字打开资源期间捕获异常
- .net - 正则表达式 - 在特定模式后开始匹配
- sql - SQL Server MS,无法识别表,已尝试所有补救措施
- service - 如何在 Flutter 中创建服务以使应用始终在后台运行?
- java - 按升序对集合中的值进行排序