数据简介
我有一个文本文件文档或csv,其中包含网站的编码,而我无法将数据导出到Excel工作表。这意味着数据本身就是一堆代码,其中的元素由某些文本位来区分。
了解数据
Fx。每个变量以<a:FN>
开头。变量x中的每个元素都有一个以<a:DT>...
开头的代码
y的代码以<a:KY>...
开头,其中该元素的值以<a:VL>
开头。
每个变量的编码以及与此变量相关的基础代码均以<a:PLI>
开头。
数据结构
So the structure of the file is as following:
`<a:PLI>`
<a:DT>...
`<a:FN>...`
`<a:KY>...`
<a:VL>...
`<a:PLI>`
<a:DT>...
`<a:FN>...`
`<a:KY>...`
<a:VL>...
当导入到R中时,数据框仅具有1列,总计大约为1。 35.000行。每段代码都有自己的行。
我想做的事和预期的结果
我想做的就是将这个复杂的文本文件转换成一个新的数据框,其中包含我感兴趣的所有元素。
例如,对于每个组/变量(a<:FN)
,我想找到X (<a:DT>)
,然后在其中找到组织机构键的Y (<a:KY>org-key</a:KY>)
和Z (<a:VL)
。
我想对所有组/变量中的所有X都执行此操作,从而得到一个输出,其中每个X都按照其尊重的Y和Z值进行分组。
我不确定如何解决我的问题。我以为可能是for循环,或者使用诸如sapply之类的应用族中的方法。坦白说,我不确定从哪里开始,这就是为什么我要伸出援手。
我打算做的是设置一个描述我要做什么的函数:
bespoke <- function (x) {
find x in df ## X could be one of the varaibles I am looking for
find y after x ## Find y for x in df
find z after x ## find z for x in df
return all elements to a df ## I wnat to repeat this function for all variables in df.
}
df2 <- adply(keys, bespoke)
我不习惯使用函数,所以我甚至都不知道该如何开始,这还因为我有很多底层函数要跟踪。
我希望有人能帮助我前进。
数据部分:
<a:PLI>
<a:DT>False</a:DT>
<a:DTR>False</a:DTR>
<a:Desc>text text text</a:Desc>
<a:FN>Type</a:FN>
<a:PSPS>
<a:PSP>
<a:KY>org-group</a:KY>
<a:VL>40100</a:VL>
</a:PSP>
<a:PSP>
<a:KY>org-key</a:KY>
<a:VL>60205</a:VL>
</a:PSP>
<a:PSP>
<a:KY>org-systemkey</a:KY>
<a:VL>1005</a:VL>
</a:PSP>
<a:PSP>
<a:KY>org-report-type</a:KY>
<a:VL>text text text</a:VL>
</a:PSP>
</a:PSPS>
<a:TI>80200</a:TI>
</a:PLI>
<a:PLI>
<a:DT>Room</a:DT>
<a:DTR>Room</a:DTR>
<a:Desc/>
<a:FN>StartRoom</a:FN>
<a:PSPS>
<a:PSP>
<a:KY>org-group</a:KY>
<a:VL>13020</a:VL>
</a:PSP>
<a:PSP>
<a:KY>org-key</a:KY>
<a:VL>13130</a:VL>
</a:PSP>
</a:PSPS>
<a:TI>12500</a:TI>
</a:PLI>
<a:PLI>
<a:DT>Other room</a:DT>
<a:DTR>Other room</a:DTR>
<a:Desc/>
<a:FN>StartRoom</a:FN>
<a:PSPS>
<a:PSP>
<a:KY>org-group</a:KY>
<a:VL>11160</a:VL>
</a:PSP>
<a:PSP>
<a:KY>org-key</a:KY>
<a:VL>15152</a:VL>
</a:PSP>
</a:PSPS>
<a:TI>15552</a:TI>
</a:PLI>
答案 0 :(得分:1)
(很抱歉以前的错误答案,我错过了您问题的重要部分)
这是我要这样做的方式:
然后,在R中:
library(xml2)
foo <- read_xml("tmp.xml")
# convert to a nodeset
allplis <- xml_find_all(foo, "//PLI")
xtractpli <- function(x) {
dt <- xml_text(xml_find_first(x, "DT"))
fn <- xml_text(xml_find_first(x, "FN"))
orgkey <- xml_find_first(x, "PSPS/PSP[KY='org-key']")
orgkey <- xml_text(xml_find_first(orgkey, "VL"))
return(c(fn, dt, orgkey))
}
t(sapply(allplis, xtractpli))
结果:
[,1] [,2] [,3]
[1,] "Type" "False" "60205"
[2,] "StartRoom" "Room" "13130"
[3,] "StartRoom" "Other room" "15152"
这是您想要的吗?
答案 1 :(得分:1)
您实际上正在处理一种XML,其中a
之前的:
被称为其“命名空间”。假设其余数据与您提供的示例相似,则可以使用以下代码提取数据,其中s
是您提供的数据(您需要替换s
和您的文件名):
library(rvest)
library(purrr)
library(dplyr)
vars <- c("dt", "dtr", "desc", "fn", "ti", "ky", "vl")
read_html(s) %>%
html_nodes("pli") %>%
unclass() %>%
map_df(~ map2(list(.), vars, ~ html_text(html_nodes(.x, .y))) %>%
set_names(vars) %>%
as_tibble,
.id = "pli"
)
我使用read_html
而不是read_xml
,因为在这种情况下,它可以很好地解析XML,而且我不喜欢在名称空间周围闲逛。我不能保证这将一直有效。在示例数据中似乎只有一个命名空间,所以也许您会没事的。
此后,我使用pli
拉出三个html_nodes
节点,然后使用unclass
将XML节点集转换为列表。在map_df
中,我遍历三个列表元素(三个pli
节点)中的每一个,并应用map2
,在其中使用vars
中的值拉出所有相关节点并将输出存储在小标题中。结果应如下所示:
# A tibble: 8 x 8
pli dt dtr desc fn ti ky vl
<chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 1 False False text text text Type 80200 org-group 40100
2 1 False False text text text Type 80200 org-key 60205
3 1 False False text text text Type 80200 org-systemkey 1005
4 1 False False text text text Type 80200 org-report-type text text text
5 2 Room Room "" StartRoom 12500 org-group 13020
6 2 Room Room "" StartRoom 12500 org-key 13130
7 3 Other room Other room "" StartRoom 15552 org-group 11160
8 3 Other room Other room "" StartRoom 15552 org-key 15152