readHTMLTable返回不完整的数据集

时间:2014-04-25 19:18:54

标签: r

几天前,用户提出了一个相当有趣的问题。有关原始问题,请参阅How to use readHTMLTable without cutting off first row

我对headerreadHTMLTable} XML中的header参数所表现出的奇怪行为感到有些好奇。在我进一步讨论之前,我可以确认我已经完成了文档并且说明了

  

“这些方法尝试进行一些启发式计算来确定   列的标题标签,表的名称等“

好的,所以我可以预期header = FALSE参数可能并不总能返回最佳结果。顺便说一下,这只适用于头参数吗?或者整个表可能不是最优的?

嗯,经过一番调查后,我发现整张表不是最佳的。它只会在header = TRUE时返回完整。设置header = NA或将其留空(URL <- "http://www.nfl.com/stats/categorystats?archive=false&conference=null&statisticPositionCategory=FIELD_GOAL_KICKER&season=2013&seasonType=REG&experience=&tabSeq=1&qualified=false&Submit=Go" library(XML) ## missing first row of table head(readHTMLTable(URL)$result[1:10], 3) ## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ## 1 1 Justin Tucker BAL K 38 41 93 0 61 0-0 ## 2 3 Adam Vinatieri IND K 35 40 88 1 52 0-0 ## 3 4 Nick Novak SD K 34 37 92 2 50 1-1 ## missing first row of table head(readHTMLTable(URL, header = TRUE)$result[1:10], 3) ## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ## 1 1 Justin Tucker BAL K 38 41 93 0 61 0-0 ## 2 3 Adam Vinatieri IND K 35 40 88 1 52 0-0 ## 3 4 Nick Novak SD K 34 37 92 2 50 1-1 )会产生缺少第一行数据的表格。

此问题的数据表位于NFL.com

我们来看看......

header = FALSE

现在让我们改为## returns complete table head(readHTMLTable(URL, header = FALSE)$result[1:10], 3) ## V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 ## 1 1 Stephen Gostkowski NE K 38 41 93 0 54 1-1 ## 2 1 Justin Tucker BAL K 38 41 93 0 61 0-0 ## 3 3 Adam Vinatieri IND K 35 40 88 1 52 0-0 。在这里,我们发现现在包含了表的第一行。

这是完整的表格。

header

重申一下,只有在FALSE设置为XML时,才会返回完整的数据集。

我意识到完全掌握HTML和XML表并不容易。但是我在数据中错过了NFL中的#1踢球者(插入“他只是一个踢球者,谁在乎?”这里的笑话。)

有没有人在R函数之前看过这样的行为?这种情况背后有逻辑吗?它可能是针对这个特定网站的吗?我可以在其他人身上测试它,但不是全部。 > sessionInfo() ## R version 3.1.0 (2014-04-10) ## Platform: x86_64-pc-linux-gnu (64-bit) 包很棒,但这让我有些不安。

会话信息(部分)

{{1}}

1 个答案:

答案 0 :(得分:3)

阅读readHTMLTable的帮助提供以下内容

  

标题

     

指示表格是否具有列标签的逻辑值,例如第一行或者thead,或者是一个字符向量,给出用于结果列的名称。这可以是一个逻辑向量,各个值将依次用于不同的表。这允许调用者控制是否将各个表处理为具有列名。或者,可以通过which参数读取特定的表,并控制如何使用单个标量逻辑处理。

现在,如果您检查要尝试读取的表,您将看到列标题由两行定义。在源代码中,您会看到这些内容已在thd1thd2中定义。

使用header=TRUEheader=NA并且没有thead节点,然后删除第一行(假设它定义了列标签)

## a code snippet from getMethod("readHTMLTable",'XMLInternalElementNode')
 headerFromTable = FALSE
 dropFirstRow = FALSE
 if (length(header) == 1 && is.na(header)) 
    header = (xmlName(doc) %in% c("table", "tbody") && 
         ("thead" %in% names(doc) || length(getNodeSet(node, 
         "./tr[1]/th | ./tr[1]/td")) > 0))
 if (is.logical(header) && (is.na(header) || header) && 
    xmlName(node) == "table") {
      if ("thead" %in% names(node)) 
            header = node[["thead"]]
           else {
             if ("tr" %in% names(node)) 
               tmp = node[["tr"]]
               else tmp = node[["tbody"]][["tr"]]
                if (!is.null(tmp) && all(names(tmp) %in% c("text", 
                  "th"))) {
                  header = xpathSApply(tmp, "./th | ./td", xmlValue, 
                    encoding = encoding)
                  dropFirstRow = TRUE
                }
            }
        }

通过设置header=FALSE,您不会删除第一行。

定义标题

  1. 手动将列标签定义为字符向量,或
  2. 使用解析HTML的中间步骤从中提取标签 thd1和/或thd2个节点。