2016-07-29 9 views
0

Rのデータフレームに異なる数または行のベクトルを結合するにはどうすればいいですか?各ベクトルは7または9の行を持ちます。 sourceVersionとdeviceは追加の2行です。私はこれらをデータフレームに含めて空白のままにしておくか、または7行のベクトル観測のためにNAに設定します(下の表を参照してください)。R行の長さが異なるベクトルを結合する

私はこのようなデータフレームにデータを必要とします。

type         sourceName    sourceVersion device                           unit creationDate startDate  endDate   value 
HKQuantityTypeIdentifierFlightsClimbed Ryan Praskievicz iPhone 9.3.2   <<HKDevice: 0x15a4af3f0>, name:iPhone, manufacturer:Apple, model:iPhone, hardware:iPhone8,1, software:9.3.2> count 6/2/2016 12:27 6/2/2016 12:09 6/2/2016 12:09 1 
HKQuantityTypeIdentifierStepCount  Ryan Praskievicz iPhone                                 count 10/2/2014 8:30 9/24/2014 15:07 9/24/2014 15:07 7 

これは私が試みたものです。

library(XML) 

xmlstr <- '<?xml version="1.0" encoding="UTF-8"?> 
      <HealthData locale="en_US"> 
       <ExportDate value="2016-06-02 14:05:23 -0400"/> 
       <Me HKCharacteristicTypeIdentifierDateOfBirth="" HKCharacteristicTypeIdentifierBiologicalSex="HKBiologicalSexNotSet" HKCharacteristicTypeIdentifierBloodType="HKBloodTypeNotSet" HKCharacteristicTypeIdentifierFitzpatrickSkinType="HKFitzpatrickSkinTypeNotSet"/> 
       <Record type="HKQuantityTypeIdentifierStepCount" sourceName="Ryan Praskievicz iPhone" unit="count" creationDate="2014-10-02 08:30:17 -0400" startDate="2014-09-24 15:07:06 -0400" endDate="2014-09-24 15:07:11 -0400" value="7"/> <Record type="HKQuantityTypeIdentifierFlightsClimbed" sourceName="Ryan Praskievicz iPhone" sourceVersion="9.3.2" device="&lt;&lt;HKDevice: 0x15a4af3f0&gt;, name:iPhone, manufacturer:Apple, model:iPhone, hardware:iPhone8,1, software:9.3.2&gt;" unit="count" creationDate="2016-06-02 12:27:46 -0400" startDate="2016-06-02 12:09:29 -0400" endDate="2016-06-02 12:09:29 -0400" value="1"/> </HealthData>' 

xml <- xmlParse(xmlstr) 

recordAttribs <- xpathSApply(doc=xml, path="//HealthData/Record", xmlAttrs) 
df <- data.frame(t(recordAttribs)) 
df 

これは、ここで私はRコンソールに出力するために何を得る

 X1 
      1 HKQuantityTypeIdentifierStepCount, Ryan Praskievicz iPhone, count, 2014-10-02 08:30:17 -0400, 2014-09-24 15:07:06 -0400, 2014-09-24 15:07:11 -0400, 7                                                                     
    X2 
1 HKQuantityTypeIdentifierFlightsClimbed, Ryan Praskievicz iPhone, 9.3.2, <<HKDevice: 0x15a4af3f0>, name:iPhone, manufacturer:Apple, model:iPhone, hardware:iPhone8,1, software:9.3.2>, count, 2016-06-02 12:27:46 -0400, 2016-06-02 12:09:29 -0400, 2016-06-02 12:09:29 -0400, 1 
+0

う[本](http://webcache.googleusercontent.com/search?q=cache:lPRvnOOSAgoJ:www.inside-r.org/packages/あなたが探していることをやっていますか? –

+0

まず、異なる数の行数の列をバインドするのではなく、異なる数の列を使用して行をバインドしようとしています。それは言われている、あなたは、一般的に列の配列の問題がありますか?つまり、ある行の列の数が他の列の数よりも少ない場合、どの列が欠落しているかをどのようにデータから推測できないかをどのように知ることができますか? – aichao

+0

@aichao同じ2行が欠落しているようです - sourceVersionとdevice。 – Warner

答えて

1

sapplylapplyを使用して、それを行うための方法です。

recordAttribs <- xpathSApply(doc=xml, path="//HealthData/Record", xmlAttrs) 

recordAttribs <- t(recordAttribs) 

リスト内の要素がこの条件を満たしているあなたのリストのサブセットに使用lapply 7.

short.condition <- sapply(recordAttribs, function(x) length(x)==7) 

に等しいかどうかに基づいてsapplyを使用してTRUE/FALSEのベクトルを取得します。

df <- matrix(unlist(recordAttribs), 
      nrow=2,ncol=9, byrow=TRUE) 

df <- data.frame(df, stringsAsFactors=FALSE) 

names(df) <- c("type","sourceName","sourceVersion","device","unit","creationDate","startDate","endDate","value") 

次のようになります:

recordAttribs[short.condition] <- lapply(recordAttribs, 
             function(x) c(x[1:2],NA,NA,x[3:7])) 

は、あなたが望む形でdata.frameにこれを変換するには:あなたが上記の条件を満たしているベクトル内の2 NAを連結しているこの時間

> str(df) 
'data.frame': 2 obs. of 9 variables: 
$ type   : chr "HKQuantityTypeIdentifierStepCount" "HKQuantityTypeIdentifierFlightsClimbed" 
$ sourceName : chr "Ryan Praskievicz iPhone" "Ryan Praskievicz iPhone" 
$ sourceVersion: chr NA "9.3.2" 
$ device  : chr NA "<<HKDevice: 0x15a4af3f0>, name:iPhone, manufacturer:Apple, model:iPhone, hardware:iPhone8,1, software:9.3.2>" 
$ unit   : chr "count" "count" 
$ creationDate : chr "2014-10-02 08:30:17 -0400" "2016-06-02 12:27:46 -0400" 
$ startDate : chr "2014-09-24 15:07:06 -0400" "2016-06-02 12:09:29 -0400" 
$ endDate  : chr "2014-09-24 15:07:11 -0400" "2016-06-02 12:09:29 -0400" 
$ value  : chr "7" "1" 
+0

答えに感謝しますが、これは私が探しているものではありません。私は私の質問の最初の表のようなデータフレーム内のデータを "私はこのようなデータフレームにデータを入れたい"の下にしたい。 –

+0

@ RyanPraskievicz私はこれを説明するために私の答えを編集しました。それは最善の解決策ではありません。私は、同じ2つの列があなたの観測で7行欠けていると仮定しています。 – Warner

+0

@RyanPraskieviczはもう1つの編集を行い、有用なdata.frameに出力を入れました。 – Warner

2

依存性が少し難解ですが、あなたが行うことができます:

library(data.table) 
rbindlist(lapply(recordAttribs, function(x) data.table(t(x))), fill=TRUE) 

data.tableを返します。data.frameを継承しています。

         type    sourceName unit 
1:  HKQuantityTypeIdentifierStepCount Ryan Praskievicz iPhone count 
2: HKQuantityTypeIdentifierFlightsClimbed Ryan Praskievicz iPhone count 
       creationDate     startDate     endDate value 
1: 2014-10-02 08:30:17 -0400 2014-09-24 15:07:06 -0400 2014-09-24 15:07:11 -0400  7 
2: 2016-06-02 12:27:46 -0400 2016-06-02 12:09:29 -0400 2016-06-02 12:09:29 -0400  1 
    sourceVersion 
1:   NA 
2:   9.3.2 
                             device 
1:                           NA 
2: <<HKDevice: 0x15a4af3f0>, name:iPhone, manufacturer:Apple, model:iPhone, hardware:iPhone8,1, software:9.3.2> 

私はdata.tableを使用している理由は、それが等しくない長さの行は、名前ではない位置に列が一致することができますuse.names=TRUEオプションでスマートrbind方法を持っているということで、NAとの欠損値を埋めます。どのようrbind.data.table作品の

よりシンプルな例:

d1 = data.table(a="foo", b = "bar", c = "baz") 
d2 = data.table(b="bar", a = "foo") 
rbind(d1, d2) # throws helpful error: "If instead you need to fill missing columns, use set argument 'fill' to TRUE." 
rbind(d1, d2, fill=TRUE) 
#  a b c 
# 1: foo bar baz 
# 2: foo bar NA 
+0

これはすばらしいおかげです!私のフル・データ・セットの 'df <-do.call(rbind、c(lapply(recordAttribs、function(x)data.table(t)()、fill = TRUE))'セクションを実行しようとすると、 recordAttribs'は大きなリスト(405677要素、464 MB)です。実行に時間がかかります。大規模なデータセットでこれを改善するために何をすべきかについてのアイデアはありますか? –

+0

@RyanPraskievicz上記のように 'rbindlist'を試してください。 'lapply'が本当にあなたを落としているなら、' multicore :: mclapply' – C8H10N4O2

関連する問題