преобразовать тройной вложенный список в фрейм данных - PullRequest
0 голосов
/ 30 апреля 2018

Я пытаюсь преобразовать тройной вложенный список в фрейм данных. Этот вопрос помог, но я не могу получить нужный мне фрейм данных.

Список представляет собой цепочку опционов, полученную от IBrokers, резюме приведено ниже. Я загрузил фактическую цепочку здесь , что более подробно.

Chain <- 
  list(
    list(
      list(
        list(version="8",contract=list(symbol="BHP",right="C",expiry="20180621",strike="25")),
        list(version="8",contract=list(symbol="BHP",right="C",expiry="20180621",strike="26"))
      ),
      list(
        list(version="8",contract=list(symbol="BHP",right="C",expiry="20180730",strike="25")),
        list(version="8",contract=list(symbol="BHP",right="C",expiry="20180730",strike="26"))
      )
    ),
    list(
      list(
        list(version="8",contract=list(symbol="CBA",right="C",expiry="20180621",strike="65")),
        list(version="8",contract=list(symbol="CBA",right="C",expiry="20180621",strike="64"))
      ),
      list(
        list(version="8",contract=list(symbol="CBA",right="C",expiry="20180730",strike="65")),
        list(version="8",contract=list(symbol="CBA",right="C",expiry="20180730",strike="64"))
      )
    )
  )

Я хотел бы преобразовать список в фрейм данных следующим образом:

Contracts <- data.frame(symbol=c("BHP","BHP","BHP","BHP","CBA","CBA","CBA","CBA"),
                        right=c("C","C","C","C","C","C","C","C"),
                        expiry=c("20180621","20180621","20180730","20180730","20180621","20180621","20180730","20180730"),
                        strike=c("25","26","25","26","65","64","65","64"))

Я попробовал этот код, но он не дал мне тот кадр данных, который я хотел.

X <- lapply(Chain,function(x) as.data.frame.list(lapply(x,as.data.frame.list)))
dfx <- do.call(rbind,X)

Есть предложения, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Вы можете использовать unstack

 unstack(data.frame(d<-unlist(Chain),names(d)))
  contract.expiry contract.right contract.strike contract.symbol version
1        20180621              C              25             BHP       8
2        20180621              C              26             BHP       8
3        20180730              C              25             BHP       8
4        20180730              C              26             BHP       8
5        20180621              C              65             CBA       8
6        20180621              C              64             CBA       8
7        20180730              C              65             CBA       8
8        20180730              C              64             CBA       8

Если хотите, можете удалить слово contract.

unstack(data.frame(d<-unlist(Chain),sub(".*[.]","",names(d))))
    expiry right strike symbol version
1 20180621     C     25    BHP       8
2 20180621     C     26    BHP       8
3 20180730     C     25    BHP       8
4 20180730     C     26    BHP       8
5 20180621     C     65    CBA       8
6 20180621     C     64    CBA       8
7 20180730     C     65    CBA       8
8 20180730     C     64    CBA       8

Это также можно записать как unstack(data.frame(d<-unlist(Chain),sub("contract[.]","",names(d)))) Хотя я бы предпочел сохранить контракт имени, чтобы узнать, какие столбцы действительно образуют необходимый фрейм данных контракта

Или даже вы можете изменить имена после unstacking.

С новыми данными:

a=readLines("https://raw.githubusercontent.com/hughandersen/OptionsTrading/master/Stocks_option_chain")
b=eval(parse(text=paste(a,collapse="")))
s=unstack(data.frame(d<-unlist(b[6]),names(d)))
0 голосов
/ 30 апреля 2018

Как насчет следующего?

df <- as.data.frame(matrix(unlist(Chain, recursive = T), ncol = 5, byrow = T)[, -1]);
colnames(df) <- c("symbol", "right", "expiry", "strike");
#  symbol right   expiry strike
#1    BHP     C 20180621     25
#2    BHP     C 20180621     26
#3    BHP     C 20180730     25
#4    BHP     C 20180730     26
#5    CBA     C 20180621     65
#6    CBA     C 20180621     64
#7    CBA     C 20180730     65
#8    CBA     C 20180730     64

Объяснение: Рекурсивно unlist вложенное Chain, затем преобразовать в matrix, удалить столбец version и преобразовать в data.frame. Единственный минус в том, что мы должны вручную добавлять имена столбцов.


Обновление

Поскольку ваши фактические данные совсем другие, здесь есть возможность. Примечание: я предполагаю, что структура из Gist хранится в tbl.

tbl;
#Source: local data frame [2 x 6]
#Groups: <by row>
#
## A tibble: 2 x 6
#  symbol sectype exch  currency multiplier Chain
#  <fct>  <fct>   <fct> <fct>    <fct>      <list>
#1 BHP    OPT     ASX   AUD      100        <list [1,241]>
#2 CBA    OPT     ASX   AUD      100        <list [1,204]>

Следующий list содержит два data.frame s, по одному для каждой строки из tbl.

lst <- lapply(tbl$Chain, function(x)
    do.call(rbind.data.frame, lapply(x, function(y) as.data.frame(unclass(y$contract)))))
#List of 2
# $ :'data.frame':  1241 obs. of  16 variables:
#  ..$ conId          : Factor w/ 1241 levels "198440202","198440207",..: 1 2 3 4 5 6 7 8 9 10 ...
#  ..$ symbol         : Factor w/ 1 level "BHP": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ sectype        : Factor w/ 1 level "OPT": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ exch           : Factor w/ 1 level "ASX": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ primary        : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ expiry         : Factor w/ 18 levels "20180628","20181220",..: 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ strike         : Factor w/ 118 levels "25","26","27",..: 1 1 2 2 3 3 4 4 5 5 ...
#  ..$ currency       : Factor w/ 1 level "AUD": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ right          : Factor w/ 2 levels "C","P": 1 2 1 2 1 2 1 2 1 2 ...
#  ..$ local          : Factor w/ 1241 levels "BHPV78","BHPV88",..: 1 2 3 4 5 6 7 8 9 10 ...
#  ..$ multiplier     : Factor w/ 1 level "100": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ combo_legs_desc: Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ comboleg       : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ include_expired: Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ secIdType      : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ secId          : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
# $ :'data.frame':  1204 obs. of  16 variables:
#  ..$ conId          : Factor w/ 1204 levels "198447027","198447030",..: 1 2 3 4 5 6 7 8 9 10 ...
#  ..$ symbol         : Factor w/ 1 level "CBA": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ sectype        : Factor w/ 1 level "OPT": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ exch           : Factor w/ 1 level "ASX": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ primary        : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ expiry         : Factor w/ 18 levels "20180628","20181220",..: 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ strike         : Factor w/ 179 levels "79.68","81.68",..: 1 1 2 2 3 3 4 4 5 5 ...
#  ..$ currency       : Factor w/ 1 level "AUD": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ right          : Factor w/ 2 levels "C","P": 1 2 1 2 1 2 1 2 1 2 ...
#  ..$ local          : Factor w/ 1204 levels "CBAKT9","CBAKU9",..: 1 2 3 4 5 6 7 8 9 10 ...
#  ..$ multiplier     : Factor w/ 1 level "100": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ combo_legs_desc: Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ comboleg       : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ include_expired: Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ secIdType      : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
#  ..$ secId          : Factor w/ 1 level "": 1 1 1 1 1 1 1 1 1 1 ...
...