Разделение значений без разделителя и неравной длины - PullRequest
0 голосов
/ 12 сентября 2018

Я удалил вторую таблицу HTML со следующего сайта

(http://www.floridahealth.gov/programs-and-services/office-of-medical-marijuana-use/medical-marijuana-treatment-centers/index.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, как показано здесь: Список после записывается в виде CSV

Я хочу отделить информацию об адресе, но нет согласованности с длиной или разделителями. Этот список будет продолжать расти иЯ сталкиваюсь с той же проблемой с другими наборами данных, поэтому я хотел бы написать код, который автоматизирует процесс разделения адресных данных. Возможно, я мог бы сделать это при очистке таблицы в первую очередь?

1 Ответ

0 голосов
/ 17 сентября 2018

Поскольку вы не указали, как вы хотите отделить адрес, я предполагаю, что каждая строка из блока адреса должна идти в отдельный столбец.
Для этого вы можете выбрать p-теги 2-й таблицы с помощьюдостаточный запрос XPath, например

//*[@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"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...