将 html table 提取到 R 中,但在具有三个 lines/rows 的特定列中跳过特定元素 (<br>),在多页 html 中
Extract html table into R but skip specific elements (<br>) in one certain column that has three lines/rows, in a multi-page html
我想将 link 中的 table 加载到 R 中的数据框中。
以下脚本成功提取 table:
install.packages("htmltab")
library(htmltabl)
url <- "http://www.hmdb.ca/metabolites?utf8=✓&filter=true&toxin=1&filter=true"
hm_ext <- htmltab(url)
但问题来了:
> head(hm_ext)
HMDB ID CAS Number Name FormulaAverage Mass Monoisotopic Mass Biospecimen Location
2 HMDB000014264-18-6 Formic acid CH2O246.025446.005479308 BloodBreast MilkCerebrospinal Fluid (CSF)FecesSalivaSweatUrine
3 HMDB0000228108-95-2 Phenol C6H6O94.111294.041864814 BloodFecesSalivaSweatUrine
4 HMDB000059818496-25-8 Sulfide S32.06531.97207069 Blood
5 HMDB00005997440-47-3 Chromium Cr51.996151.940511904 BloodCerebrospinal Fluid (CSF)SalivaUrine
6 HMDB00006577440-50-8 Copper Cu63.54662.929601079 BloodCerebrospinal Fluid (CSF)SalivaUrine
7 HMDB00006627782-41-4 Fluoride F18.998418.998403205 BloodSalivaUrine
第三列,即Formula Average Mass Monoisotopic Mass
,有三个rows/values/lines,它们都混合在一起,因此显示为一个连续的字符串。 我只想提取此列中的第一个 line/row 或以某种方式将这三个值彼此分开。
这是呈现的 html 页面中第三列的第一个单元格的样子:
third column screenshot
如果我使用 XML::readHTMLTable
,也会发生同样的事情。
当我点击Chrome中的Inspect Element
时,我可以在Formula Average Mass Monoisotopic Mass
列中看到这样一个单元格结构:
<td class="weight-value">CH<sub>2</sub>O<sub>2</sub><br><br>46.0254<br>46.005479308</td>
image -- please embed it. I do not have enough reputation to do that
不过,也有其他时候这一栏的第二行和第三行是空的。示例:
<td class="weight-value">(C<sub>12</sub>H<sub>19</sub>NO<sub>19</sub>S<sub>3</sub>)nH<sub>2</sub>O<br><br><span class="wishart wishart-not-available">Not Available</span><br></td>
image -- Inspect Element screenshot
那么如何从给定的 link 中提取 table 但保持第三列的结构可读且不混淆? 而且, 是否可以提取所有页面中的 tables 而无需循环遍历每个单独页面的 links?
其中一种方法可能是
library(rvest)
library(qdapRegex)
library(XML)
#read webpage
htm_data <- read_html("http://www.hmdb.ca/metabolites?tf8=%E2%9C%93&filter=true&toxin=1&filter=true")
#convert above webpage's table into a dataframe
df <- html_table(html_nodes(htm_data, "table"))[[1]]
#cleanup data in the required column
df[, 4] <- unlist(lapply(rm_between(xml_find_all(htm_data, "//table/tbody/tr/td[4]"),
">",
"<br><br>", extract=TRUE),
function(x) gsub("<.*?>", "", x[[1]])))
这给出了
> head(df)
HMDB ID CAS Number Name Structure FormulaAverage Mass Monoisotopic Mass
1 HMDB000014264-18-6 Formic acid NA CH2O2
2 HMDB0000228108-95-2 Phenol NA C6H6O
3 HMDB000059818496-25-8 Sulfide NA S
4 HMDB00005997440-47-3 Chromium NA Cr
5 HMDB00006577440-50-8 Copper NA Cu
6 HMDB00006627782-41-4 Fluoride NA F
Biospecimen Location
1 BloodBreast MilkCerebrospinal Fluid (CSF)FecesSalivaSweatUrine
2 BloodFecesSalivaSweatUrine
3 Blood
4 BloodCerebrospinal Fluid (CSF)SalivaUrine
5 BloodCerebrospinal Fluid (CSF)SalivaUrine
6 BloodSalivaUrine
我想将 link 中的 table 加载到 R 中的数据框中。
以下脚本成功提取 table:
install.packages("htmltab")
library(htmltabl)
url <- "http://www.hmdb.ca/metabolites?utf8=✓&filter=true&toxin=1&filter=true"
hm_ext <- htmltab(url)
但问题来了:
> head(hm_ext)
HMDB ID CAS Number Name FormulaAverage Mass Monoisotopic Mass Biospecimen Location
2 HMDB000014264-18-6 Formic acid CH2O246.025446.005479308 BloodBreast MilkCerebrospinal Fluid (CSF)FecesSalivaSweatUrine
3 HMDB0000228108-95-2 Phenol C6H6O94.111294.041864814 BloodFecesSalivaSweatUrine
4 HMDB000059818496-25-8 Sulfide S32.06531.97207069 Blood
5 HMDB00005997440-47-3 Chromium Cr51.996151.940511904 BloodCerebrospinal Fluid (CSF)SalivaUrine
6 HMDB00006577440-50-8 Copper Cu63.54662.929601079 BloodCerebrospinal Fluid (CSF)SalivaUrine
7 HMDB00006627782-41-4 Fluoride F18.998418.998403205 BloodSalivaUrine
第三列,即Formula Average Mass Monoisotopic Mass
,有三个rows/values/lines,它们都混合在一起,因此显示为一个连续的字符串。 我只想提取此列中的第一个 line/row 或以某种方式将这三个值彼此分开。
这是呈现的 html 页面中第三列的第一个单元格的样子:
third column screenshot
如果我使用 XML::readHTMLTable
,也会发生同样的事情。
当我点击Chrome中的Inspect Element
时,我可以在Formula Average Mass Monoisotopic Mass
列中看到这样一个单元格结构:
<td class="weight-value">CH<sub>2</sub>O<sub>2</sub><br><br>46.0254<br>46.005479308</td>
image -- please embed it. I do not have enough reputation to do that
不过,也有其他时候这一栏的第二行和第三行是空的。示例:
<td class="weight-value">(C<sub>12</sub>H<sub>19</sub>NO<sub>19</sub>S<sub>3</sub>)nH<sub>2</sub>O<br><br><span class="wishart wishart-not-available">Not Available</span><br></td>
image -- Inspect Element screenshot
那么如何从给定的 link 中提取 table 但保持第三列的结构可读且不混淆? 而且, 是否可以提取所有页面中的 tables 而无需循环遍历每个单独页面的 links?
其中一种方法可能是
library(rvest)
library(qdapRegex)
library(XML)
#read webpage
htm_data <- read_html("http://www.hmdb.ca/metabolites?tf8=%E2%9C%93&filter=true&toxin=1&filter=true")
#convert above webpage's table into a dataframe
df <- html_table(html_nodes(htm_data, "table"))[[1]]
#cleanup data in the required column
df[, 4] <- unlist(lapply(rm_between(xml_find_all(htm_data, "//table/tbody/tr/td[4]"),
">",
"<br><br>", extract=TRUE),
function(x) gsub("<.*?>", "", x[[1]])))
这给出了
> head(df)
HMDB ID CAS Number Name Structure FormulaAverage Mass Monoisotopic Mass
1 HMDB000014264-18-6 Formic acid NA CH2O2
2 HMDB0000228108-95-2 Phenol NA C6H6O
3 HMDB000059818496-25-8 Sulfide NA S
4 HMDB00005997440-47-3 Chromium NA Cr
5 HMDB00006577440-50-8 Copper NA Cu
6 HMDB00006627782-41-4 Fluoride NA F
Biospecimen Location
1 BloodBreast MilkCerebrospinal Fluid (CSF)FecesSalivaSweatUrine
2 BloodFecesSalivaSweatUrine
3 Blood
4 BloodCerebrospinal Fluid (CSF)SalivaUrine
5 BloodCerebrospinal Fluid (CSF)SalivaUrine
6 BloodSalivaUrine