How to avoid renaming of rows when using rbind inside do.call?
Asked Answered
C

1

13

I am trying to bind some sub elements of the elements from the list

The list OC is as follows

> library(quantmod)
> OC <- getOptionChain('AAPL', NULL)

> str(OC)
List of 9
 $ Feb 2013:List of 3
  ..$ calls :'data.frame':  35 obs. of  7 variables:
  .. ..$ Strike: num [1:35] 380 390 400 410 420 430 440 445 450 455 ...
  .. ..$ Last  : num [1:35] 89.9 86 60 49.5 39.8 ...
  .. ..$ Chg   : num [1:35] 0 0 -0.4 -4.4 -0.7 -1.9 -0.55 -0.7 -0.95 -1 ...
  .. ..$ Bid   : num [1:35] 79.5 69.8 59.8 49.8 39.6 ...
  .. ..$ Ask   : num [1:35] 80.2 70.2 60.2 50.2 40.2 ...
  .. ..$ Vol   : num [1:35] 1 1 48 11 61 ...
  .. ..$ OI    : num [1:35] 2 2 55 29 41 ...
  ..$ puts  :'data.frame':  40 obs. of  7 variables:
  .. ..$ Strike: num [1:40] 380 385 390 395 400 405 410 415 420 425 ...
  .. ..$ Last  : num [1:40] 0.01 0.05 0.07 0.08 0.03 0.04 0.02 0.04 0.06 0.06 ...
  .. ..$ Chg   : num [1:40] -0.03 0 0 0 -0.08 -0.06 -0.1 -0.08 -0.11 -0.17 ...
  .. ..$ Bid   : num [1:40] NA 0.01 NA NA 0.02 0.01 0.01 0.04 0.05 0.06 ...
  .. ..$ Ask   : num [1:40] 0.01 0.02 0.03 0.03 0.03 0.04 0.06 0.06 0.07 0.09 ...
  .. ..$ Vol   : num [1:40] 15 122 1 117 186 ...
  .. ..$ OI    : num [1:40] 120 99 638 95 1319 ...
  ..$ symbol: chr "AAPL"
 $ Mar 2013:List of 3
  ..$ calls :'data.frame':  221 obs. of  7 variables:
  .. ..$ Strike: num [1:221] 255 265 
##.............truncated manually for post...........

I am doing basic rbind of all the puts dataframe inside each list element of OC,

> allputs <- do.call('rbind', lapply(OC, FUN = function(x) x$puts))
> head(allputs)
                             Strike Last   Chg  Bid  Ask Vol   OI
Feb 2013.AAPL130222P00380000    380 0.01 -0.03   NA 0.01  15  120
Feb 2013.AAPL130222P00385000    385 0.05  0.00 0.01 0.02 122   99
Feb 2013.AAPL130222P00390000    390 0.07  0.00   NA 0.03   1  638
Feb 2013.AAPL130222P00395000    395 0.08  0.00   NA 0.03 117   95
Feb 2013.AAPL130222P00400000    400 0.03 -0.08 0.02 0.03 186 1319
Feb 2013.AAPL130222P00405000    405 0.04 -0.06 0.01 0.04   1   76

However, each rowname gets prepended with name of it parent element. Is there a way to avoid that?

I tried setting deparse.level = 0 for rbind, but result is not what I want..

> allputs <- do.call('rbind', list(lapply(OC, FUN = function(x) x$puts), deparse.level=0))
> head(allputs)
     Feb 2013 Mar 2013 Apr 2013 May 2013 Jun 2013 Jul 2013 Oct 2013 Jan 2014 Jan 2015
[1,] List,7   List,7   List,7   List,7   List,7   List,7   List,7   List,7   List,7  

> str(allputs[1])
List of 1
 $ :'data.frame':   40 obs. of  7 variables:
  ..$ Strike: num [1:40] 380 385 390 395 400 405 410 415 420 425 ...
  ..$ Last  : num [1:40] 0.01 0.05 0.07 0.08 0.03 0.04 0.02 0.04 0.06 0.06 ...
  ..$ Chg   : num [1:40] -0.03 0 0 0 -0.08 -0.06 -0.1 -0.08 -0.11 -0.17 ...
  ..$ Bid   : num [1:40] NA 0.01 NA NA 0.02 0.01 0.01 0.04 0.05 0.06 ...
  ..$ Ask   : num [1:40] 0.01 0.02 0.03 0.03 0.03 0.04 0.06 0.06 0.07 0.09 ...
  ..$ Vol   : num [1:40] 15 122 1 117 186 ...
  ..$ OI    : num [1:40] 120 99 638 95 1319 ...
> str(allputs[2])
List of 1
 $ :'data.frame':   207 obs. of  7 variables:
  ..$ Strike: num [1:207] 255 260 265 270 275 280 285 290 295 300 ...
  ..$ Last  : num [1:207] 0.08 0.03 0.06 0.01 0.03 0.1 0.02 0.02 0.05 0.02 ...
  ..$ Chg   : num [1:207] 0 0.02 0 0 0 0 0 0 0 0 ...
  ..$ Bid   : num [1:207] NA NA NA NA NA NA NA NA NA NA ...
  ..$ Ask   : num [1:207] 0.02 0.01 0.02 0.02 0.02 0.02 0.02 0.03 0.03 0.03 ...
  ..$ Vol   : num [1:207] 5 30 5 10 3 6 1 10 5 2 ...
  ..$ OI    : num [1:207] 33 668 541 512 455 ...
Concierge answered 20/2, 2013 at 5:38 Comment(1)
The way to do this in base R is to unname the list that you pass to rbind: do.call('rbind', unname(lapply(OC, FUN = function(x) x$puts)))Rumen
L
15

You can avoid do.call(rbind,...) by using data.table::rbindlist.

This will return a data.table. data.tables don't have rownames.

It is also blindingly fast!

library(data.table)
allputs <- rbindlist(lapply(OC, FUN = function(x) x$puts))
# my eyes, I'm blinded!

If you want to include the original rownames as a column then

lputs <- lapply(OC, FUN = function(x) x$puts)


 allputs <- rbindlist(lputs)
 # add the column with rownames
 allputs[,rn := unlist(lapply(lputs, rownames))]

If you don't want to move to data.tables, then you could set the parent names to NULL

 names(lputs) <- NULL

 do.call('rbind', lputs)
Lindahl answered 20/2, 2013 at 5:43 Comment(2)
caveat here is that rbindlist already expects each item to be a uniform list, data.frame or data.table. is there a way to use the args param of do.call to pass rbind a row.names = F or something?Fossiliferous
@Fossiliferous You may use do.call(rbind, c(yourlist, make.row.names = FALSE)); ; see the second example in ?do.call: "if we already have a list [...] we need c() to add further arguments"Vanzandt

© 2022 - 2024 — McMap. All rights reserved.