Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cbind support for deparse.level #358

Closed
ethanbsmith opened this issue Oct 11, 2021 · 6 comments
Closed

cbind support for deparse.level #358

ethanbsmith opened this issue Oct 11, 2021 · 6 comments

Comments

@ethanbsmith
Copy link
Contributor

ethanbsmith commented Oct 11, 2021

current cbind.xts does not support naming columns during the bind. this syntaxt can be very convenient vs having the capture the output followed by a colnames()<-

Desired behavior

from the base cbind docs:

deparse.level:
integer controlling the construction of labels in the case of non-matrix-like arguments (for the default method):
deparse.level = 0 constructs no labels; the default,
deparse.level = 1 or 2 constructs labels from the argument names, see the ‘Value’ section below.

I should add that i current use a wrapper function for this so if its complicated, not worth the trouble:

ApplyNames <- function (x, n) {
  names(x) <- n
  x
}

which allows me to do a single line like:

ApplyNames(cbind(foo,bar), c("foo", "bar"))
@joshuaulrich
Copy link
Owner

Can you give a reproducible example of a call to cbind(), its results, and your desired results? A dput() of the xts objects you use would be helpful.

@ethanbsmith
Copy link
Contributor Author

ethanbsmith commented Oct 17, 2021

my real world use case leverages a utility function ApplyTechnical <- function(Symbols, data, FUN, ...) that you can think of as a multithreaded version of eapply. it just farms function across a cluster, passing an OHLCV from a data cache. So im often writing code like:
ApplyTechnical(Symbols, data, function(z){cbind(ROC(z, n= 5), ROC(z, n=20))})
What i do is use the cluster to do the costly calculations in scale then bring all the results together and rbind them into a data.table for analysis.
I don't want to bring any of that complexity here, so here is a simple reproducible example:

z <- getSymbols("SPY", auto.assign = F)
cbind(z, roc20 = ROC(Cl(z), n = 20), roc50 = ROC(Cl(z), n=50))

#> tail(cbind(z, roc20 = ROC(Cl(z), n = 20), roc50 = ROC(Cl(z), n=50)))
#                                  Open   High    Low  Close   Volume      Close.1      Close.2
#2021-Oct-08 00:00:00.000  -0600 439.48 439.89 437.19 437.86 74557404 -0.013933130 -0.003121482
#2021-Oct-11 00:00:00.000  -0600 437.16 440.26 434.62 434.69 65233285 -0.023755219 -0.005519280
#2021-Oct-12 00:00:00.000  -0600 435.67 436.10 432.78 433.62 71181163 -0.020808594 -0.005883621
#2021-Oct-13 00:00:00.000  -0600 434.71 436.05 431.54 435.18 72973979 -0.025535398 -0.010395012
#2021-Oct-14 00:00:00.000  -0600 439.08 442.66 438.58 442.50 70236825 -0.007268168  0.011216814
#2021-Oct-15 00:00:00.000  -0600 444.75 446.26 444.09 445.87 66260210  0.010075936  0.012490885

Desired Results

#                                  Open   High    Low  Close   Volume      roc20      roc50
#2021-Oct-08 00:00:00.000  -0600 439.48 439.89 437.19 437.86 74557404 -0.013933130 -0.003121482
#2021-Oct-11 00:00:00.000  -0600 437.16 440.26 434.62 434.69 65233285 -0.023755219 -0.005519280
#2021-Oct-12 00:00:00.000  -0600 435.67 436.10 432.78 433.62 71181163 -0.020808594 -0.005883621
#2021-Oct-13 00:00:00.000  -0600 434.71 436.05 431.54 435.18 72973979 -0.025535398 -0.010395012
#2021-Oct-14 00:00:00.000  -0600 439.08 442.66 438.58 442.50 70236825 -0.007268168  0.011216814
#2021-Oct-15 00:00:00.000  -0600 444.75 446.26 444.09 445.87 66260210  0.010075936  0.012490885

@ethanbsmith
Copy link
Contributor Author

the advantage the a deparse solution has is that it would allow me to only rename the things that need it. Also it would get me out of the mess of having to keep track of names by order like my ApplyNames workaround does

@joshuaulrich
Copy link
Owner

joshuaulrich commented Oct 17, 2021

One workaround is to use drop() to remove the dimension (and column name) from the univariate objects you're binding.

cb <-
cbind(z,
      roc20 = drop(ROC(Cl(z), n = 20)),
      roc50 = drop(ROC(Cl(z), n = 50))
)
tail(cb[,-(1:3)])                                                                          
##            SPY.Close SPY.Volume SPY.Adjusted       roc20        roc50
## 2021-10-08    437.86   74492900       437.86 -0.01716337 -0.006351706
## 2021-10-11    434.69   65233300       434.69 -0.02698539 -0.008749501
## 2021-10-12    433.62   71181200       433.62 -0.02403884 -0.009113827
## 2021-10-13    435.18   72974000       435.18 -0.02876563 -0.013625218
## 2021-10-14    442.50   70236800       442.50 -0.01049840  0.007986585
## 2021-10-15    445.87   66226800       445.87  0.01007594  0.009260648

The underlying issue is how merge.xts() handles column names, so it might take some time to get this changed. merge.xts() is central to the entire package's functionality, so we have to be very careful not to break things when making changes.

@ethanbsmith
Copy link
Contributor Author

ethanbsmith commented Oct 17, 2021 via email

@ethanbsmith
Copy link
Contributor Author

  • this is 100% a univariate issue
  • base r also ignores the parameter name on cbind of a matrix, even if it only has 1 column

im going to close this issue, as i no longer think xts should handle this differently. in fact, i think drop is probably the correct way to deal with this, rather than having cbind special case a single column matrix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants