2017-09-06 14 views
0

私はRにはかなり新しいです。昨日ログインが必要なウェブサイトを拝見しました。このページは以下のようなXML形式です。ループを使用してリストからデータを抽出するR

<result status="success"> 
    <code>1</code> 
    <note>success</note> 
    <teacherList> 
    <teacher id="D95"> 
     <name>Mary</name> 
     <department id="420"> 
     <name>Math</name> 
     </department> 
     <department id="421"> 
     <name>Statistics</name> 
     </department> 
    </teacher> 
    <teacher id="D73"> 
     <name>Adam</name> 
     <department id="412"> 
     <name>English</name> 
     </department> 
    </teacher> 
    </teacherList> 
</result> 

最近、XMLをリストに変換しました。

library(XML) 
library(rvest) 
library(plyr) 
library(dplyr) 
library(httr) 
library(pipeR) 
library(xml2) 

url.address <- "http://xxxxxxxxxxxxxxxxx" 
session <-html_session(url.address) 
form <-html_form(read_html(url.address))[[1]] 
filled_form <- set_values(form, 
          "userid" = "id", 
          "Password" = "password") 
s <- submit_form(session,filled_form) 
z = read_xml(s$response) 
z1 = as_list(z) 
z2 <- z1$teacherList 

ここで、リストからデータを抽出してデータフレームとして作成する必要があります。ところで、一部の人は2つの部門に属しているが、一部のみがリストZ2の一部は、以下のように見える1に属している:私は一つずつを抽出

z2[[1]] 

$name 
$name[[1]] 
[1] "Mary" 


$department 
$department$name 
$department$name[[1]] 
[1] "Math" 


attr(,"id") 
[1] "420" 

$department 
$department$name 
$department$name[[1]] 
[1] "statistics" 


attr(,"id") 
[1] "421" 

attr(,"id") 
[1] "D95236" 

が、それは時間がかかりすぎた:

attr(z2[[1]],"id") 

"D95"

z2[[1]][[1]][[1]] 

"メアリー"

z2[[1]][[2]][[1]][[1]] 

"数学"

attr(z2[[1]][[2]], "id") 

"420"

z2[[1]][[3]][[1]][[1]] 

"統計"

attr(z2[[1]][[3]], "id") 

"421"

attr(z2[[2]],"id") 

"D73"

z2[[2]][[1]][[1]] 

"アダム"

z2[[2]][[2]][[1]][[1]] 

"英語"

attr(z2[[2]][[2]],"id") 

"412"

は、だから私はループを記述してみました:

for (x in 1:2){ 
    for (y in 2:3){ 
    a <- attr(z2[[x]],"id") 
    b <- z2[[x]][[1]][[1]] 
    d <- z2[[x]][[y]][[1]][[1]] 
    e <- attr(z2[[x]][[y]],"id") 
    g <- cbind(print(a),print(b),print(d),print(e)) 
    }} 

が、それはdoesnの仲間の何人かからは全く働かない1つの部門にしか属していません。私は結果が予想:

enter image description here

を何かアドバイスをいただければ幸いです!

dput(head(z2, 10)) 

structure(list(teacher = structure(list(name = list("Mary"), 
    department = structure(list(name = list("Math")), .Names = "name", id = "420"), 
    department = structure(list(name = list("statistics")), .Names = "name", id = "421")), .Names = c("name", 
"department", "department"), id = "D95"), teacher = structure(list(
    name = list("Adam"), department = structure(list(name = list(
     "English")), .Names = "name", id = "412")), .Names = c("name", 
"department"), id = "D73"), teacher = structure(list(name = list(
    "Kevin"), department = structure(list(name = list("Chinese")), .Names = "name", id = "201")), .Names = c("name", 
"department"), id = "D101"), teacher = structure(list(name = list(
    "Nana"), department = structure(list(name = list("Science")), .Names = "name", id = "205")), .Names = c("name", 
"department"), id = "D58"), teacher = structure(list(name = list(
    "Nelson"), department = structure(list(name = list("Music")), .Names = "name", id = "370")), .Names = c("name", 
"department"), id = "D14"), teacher = structure(list(name = list(
    "Esther"), department = structure(list(name = list("Medicine")), .Names = "name", id = "361")), .Names = c("name", 
"department"), id = "D28"), teacher = structure(list(name = list(
    "Mia"), department = structure(list(name = list("Chemistry")), .Names = "name", id = "326")), .Names = c("name", 
"department"), id = "D17"), teacher = structure(list(name = list(
    "Jack"), department = structure(list(name = list("German")), .Names = "name", id = "306")), .Names = c("name", 
"department"), id = "D80"), teacher = structure(list(name = list(
    "Tom"), department = structure(list(name = list("French")), .Names = "name", id = "360")), .Names = c("name", 
"department"), id = "D53"), teacher = structure(list(name = list(
    "Allen"), department = structure(list(name = list("Spanish")), .Names = "name", id = "322")), .Names = c("name", 
"department"), id = "D18")), .Names = c("teacher", "teacher", 
"teacher", "teacher", "teacher", "teacher", "teacher", "teacher", "teacher", 
"teacher")) 
+0

再現可能なデータの例を提示しない限り、援助することはできません。 'dput(head(z2、10))'を試して、結果をあなたの質問に貼り付けてください。 – lmo

+0

@lmo申し訳ありません!ちょうど追加されました: – Ching

+1

コードの画像を貼り付けてはいけません。そして、[すばらしい再現可能な例を作る方法](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) – C8H10N4O2

答えて

2

これは少し構いませんでしたが、多かれ少なかれ、以前のバージョンの投稿に投稿された出力と多かれ少なかれ一致していると思います。私はsapplylapply関数内で使用して、2番目のID変数を引き出す必要がありました。

do.call(rbind,    # rbind list of data.frames output by lapply 
     lapply(unname(z2), # loop through list, first drop outer names 
       function(x) { # begin lapply function 
       temp <- unlist(x) # unlist inner elements to a vector 
       data.frame(name=temp[names(temp) == "name"], # subset on names 
          dept=temp[names(temp) == "department.name"], # subset on dept 
          id=attr(x, "id"), # extract one id 
          id2=unlist(sapply(x, attr, "id")), # extract other id 
          row.names=NULL) # end data.frame function, drop row.names 
          })) # end lapply function, lapply, and do.call 

これにより、第2リストの構造は初期の例のいくつかの方法で異なる

 name  dept id id2 
1 Mary  Math D95 420 
2 Mary statistics D95 421 
3 Adam English D73 412 
4 Kevin Chinese D101 201 
5 Nana Science D58 205 
6 Nelson  Music D14 370 
7 Esther Medicine D28 361 
8  Mia Chemistry D17 326 
9 Jack  German D80 306 
10 Tom  French D53 360 
11 Allen Spanish D18 322 

を返します。最初に、1つのネストが削除されます。つまり、新しいリストの深さは最初の例の深さよりも1つ小さいです。 z2 [[1]]を初期リストとして提供したかのようになります。第2の例では、最初にidと呼んでいたもの(D95やD101などの値)が欠落しています。元のコードの操作のビットで、私はこれは

lapply(list(z3), # loop through list, first drop outer names 
     function(x) { # begin lapply function 
      temp <- unlist(x) # unlist inner elements to a vector 
      data.frame(name=temp[names(temp) == "name"], # subset on names 
         dept=temp[names(temp) == "department.name"], # subset on dept 
         # id=attr(x, "id"), # extract one id 
         id2=unlist(sapply(x, attr, "id")), # extract other id 
         row.names=NULL) # end data.frame function, drop row.names 
     }) 

とZ2がlapplyへの最初の引数としてlist(z3)によって置き換えられる前に、私が言及したどのようなコードのアドレスへの変更を動作するようになった

、どの必要なリストの深さを構成します。また、内部関数id=attr(x, "id"),の行は、id2が存在しないためコメントアウトされています。

+0

これは非常にきれいです!ありがとうございました:) – Ching

+0

私はdoを使用しようとしました。構造体の少ない別のものを解決するために関数をコールするが、 "data.frame(name(temp)==" name "、division = temp [names(temp)==: の引数の数は行:1、0 "あなたは親切に、どの部分が間違っているか教えてくれますか?ちょうどヒントでも大丈夫です:)私はちょうどそれを上にリストします – Ching

+0

@Ching 2番目の例で動作するようにコードを修正しました。問題に取り組む際に基礎となるデータ構造を理解することが重要です。ここでは、画面に小さな例を印刷したときに、この変数にid変数がないことがわかりました。 – lmo

0

XMLは一般的にループを記述することを避けるためにR

使用library(XML)library(plyr)に対処するのは、非常に簡単です:

ステップ1は、私が保存されたXML

で読み取ることがありますサンプルXMLはDemo.xmlという.xmlファイルです。 xmlParseにURLを渡すこともできます。

rawXML <- xmlParse("Demo.xml")

次に、リストにXMLを変換します。

xmlList <- xmlToList(rawXML)

次にあなたが提供する場合、これは、一般的なプロセスであるplyr

df1 <- ldply(xmlList, data.frame)

でデータフレームにリストを変換しますサンプルデータはあなたのものと一致するように修正することができます特定のユースケース。

結果の概要出力は次のとおりです。これはあなたが探しているものですか?

str(df1) 
'data.frame': 4 obs. of 12 variables: 
$ .id      : chr "code" "note" "teacherList" ".attrs" 
$ X..i..      : Factor w/ 2 levels "1","success": 1 2 NA 2 
$ teacher.name    : Factor w/ 1 level "Mary": NA NA 1 NA 
$ teacher.department.name : Factor w/ 1 level "Math": NA NA 1 NA 
$ teacher.department..attrs : Factor w/ 1 level "420": NA NA 1 NA 
$ teacher.department.name.1 : Factor w/ 1 level "Statistics": NA NA 1 NA 
$ teacher.department..attrs.1: Factor w/ 1 level "421": NA NA 1 NA 
$ teacher..attrs    : Factor w/ 1 level "D95": NA NA 1 NA 
$ teacher.name.1    : Factor w/ 1 level "Adam": NA NA 1 NA 
$ teacher.department.name.2 : Factor w/ 1 level "English": NA NA 1 NA 
$ teacher.department..attrs.2: Factor w/ 1 level "412": NA NA 1 NA 
$ teacher..attrs.1   : Factor w/ 1 level "D73": NA NA 1 NA 
+0

こんにちは!実際にはxml形式のログインウェブサイトを拝見したので、それを解析するのは難しいですね。 – Ching

+0

@Ching XMLシートへのリンクを提供できますか? – Mako212

+0

私はちょうどしました。私はそれを編集するために私をしました:) – Ching

関連する問題