RobinHankin / onion

R functionality to deal with quaternions and octonions
6 stars 1 forks source link

is.matrix #16

Open ggrothendieck opened 3 years ago

ggrothendieck commented 3 years ago

I assume that the following should return TRUE but returns FALSE. (I am using the version of onion on github.)

example(onionmat)
is.matrix(M)
## [1] FALSE

Also as.matrix(M) gives an error.

RobinHankin commented 3 years ago

Hello Gabor! It's great to have feedback from such an illustrious R citizen!

Both is.matrix() and as.matrix() are behaving as intended . . . but I am not 100% clear that my intentions were optimal. My thinking for is.matrix() was that the onionmat S4 class didn't actually use any base R matrix methods so it didn't make sense to classify an onionmat as a matrix. For as.matrix() I decided against coercing the elements to their real component on the grounds that one would use Re(M) for this which IMHO is much clearer and less prone to misinterpretation.

But I would be very keen to hear your views on this line of logic. Best wishes, Robin

ggrothendieck commented 3 years ago

The zoo package can take a matrix and optionally an index and produce a zoo time series object and I was thinking that perhaps onionmat objects could be accepted as the matrix. Right now it does work with complex numbers. For example suppose you have a zoo object whose matrix has k columns and you want to create an object with both the original columns and the cumulative sum of each column. Then one could use the k original columns as the real part and the k cumulative sum columns as the imaginary part. If it worked with onionmat objects then one could have groups containing up to 8 columns whereas complex numbers only allows 2 columns per group. I looked at zoo briefly for this and it seems like it might be more work than I have time and also I am not sure if onionmat objects are appropriate for that purpose in the first place but that was the motivation for all this.

This is sufficient to create a zoo object out of an onionmat object but it seems you can't really do anything with it since zoo was not written to handle them.

onionmat2zoo <- function(x, index = 1:nrow(x)) {
  structure(x, index = index, class = "zoo")
}

library(onion)
library(zoo)
example(onionmat)
z <- zoo(M)

Another example is if you have open, high, low, close, volume for kk stocks and wanted to store each one as a "column" in a zoo object. complex numbers could store close and volume and that is not enough to store the whole set for each stock.

RobinHankin commented 3 years ago

For your use-case above, I'd say that it would be more logical to use onion objects as the data slot in a zoo object as opposed to onionmats, but:

> Z.index <- as.Date(sample(12450:12500, 10))
> zoo(roct(10),Z.index)
Error in zoo(roct(10), Z.index) : 
  “x” : attempt to define invalid zoo object

I think this is because onions are not atomic, but I don't really know. But one can coerce onions to matrices and this works nicely with zoo:

 > zoo(t(as.matrix(rquat(10))),Z.index)
                   Re          i          j          k
2004-02-05 -0.2945479  0.8590058  0.2137959  1.5069207
2004-02-08 -0.8306839  0.3532442 -0.1743502 -0.1657836
2004-02-09 -0.7029508 -1.1047314  0.6169779 -0.9261736
2004-02-11 -0.5954513 -0.1055843 -0.4121480  0.9767220
2004-02-16 -0.3488176 -2.1899351  1.2120998  1.4703500
2004-02-23 -1.4879354  0.4208233 -0.4717764 -0.3659827
2004-02-29  0.3542739 -0.8775648  1.1402549  1.0406869
2004-03-09 -0.4155912  1.0725884 -0.5726180 -0.0546667
2004-03-13 -1.0634629  0.3341091 -0.1877499  0.3736492
2004-03-19 -1.0182424 -0.1126337 -0.8815027  0.7590142
> 

Thoughts?

ggrothendieck commented 3 years ago

This is only useful if there can be multiple column objects since the whole purpose of this is to have columns which themselves are groups of columns. If there were only one column then you don't need this in the first place.

zoo(matrix(rquat(10), 5, 2))

Error in zoo(matrix(rquat(10), 5, 2)) : “x” : attempt to define invalid zoo object

On Wed, Jan 20, 2021 at 12:06 AM Robin Hankin notifications@github.com wrote:

For your use-case above, I'd say that it would be more logical to use onion objects as the data slot in a zoo object as opposed to onionmats, but:

Z.index <- as.Date(sample(12450:12500, 10))

zoo(roct(10),Z.index)

Error in zoo(roct(10), Z.index) :

“x” : attempt to define invalid zoo object

I think this is because onions are not atomic, but I don't really know. But one can coerce onions to matrices and this works nicely with zoo:

zoo(t(as.matrix(rquat(10))),Z.index)

               Re          i          j          k

2004-02-05 -0.2945479 0.8590058 0.2137959 1.5069207

2004-02-08 -0.8306839 0.3532442 -0.1743502 -0.1657836

2004-02-09 -0.7029508 -1.1047314 0.6169779 -0.9261736

2004-02-11 -0.5954513 -0.1055843 -0.4121480 0.9767220

2004-02-16 -0.3488176 -2.1899351 1.2120998 1.4703500

2004-02-23 -1.4879354 0.4208233 -0.4717764 -0.3659827

2004-02-29 0.3542739 -0.8775648 1.1402549 1.0406869

2004-03-09 -0.4155912 1.0725884 -0.5726180 -0.0546667

2004-03-13 -1.0634629 0.3341091 -0.1877499 0.3736492

2004-03-19 -1.0182424 -0.1126337 -0.8815027 0.7590142

Thoughts?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/RobinHankin/onion/issues/16#issuecomment-763335080, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB32F7VAL6EF5HVWQHW5XNLS2ZQF5ANCNFSM4WJKRHHA .

-- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com

RobinHankin commented 3 years ago

I hadn't appreciated that you wanted to deal with groups of columns as a unit. I have been toying with the idea of generalizing the format of an onionmat [which is a two element list, the first being a data vector and the second an integer matrix used for indexing] so that the data vector is a list and the indexing is done by an array. Would this be interesting?

ggrothendieck commented 3 years ago

I think a tuple type that generalizes complex numbers to k components rather than 2 is what would be nice. Here is how complex numbers are used:

library(quantmod); tickers <- c("AAPL", "FB", "TSLA"); getSymbols(tickers, env = stocks <- new.env()); z <- do.call("merge", eapply(stocks, function(x) Cl(as.zoo(x)) + Vo(as.zoo(x)) * 1i))

At this point z holds three complex columns. The first has the close and volume for AAPL, the next has the close and volume for FB and the last has the close and volume for TSLA. If complex numbers could hold 6 components then the Open, High, Low and Adjusted Close could have been included as well.

I am concerned that the whole design of zoo might make it hard to incorporate non-atomic objects without a lot of work. Not sure if it would be easier with xts. xts recently added complex data but that is still atomic so easier than a complex class. The best would be if R had an atomic tuple type. In that case it might be that the zoo package could handle it without any changes at all.

z TSLA AAPL FB 2021-01-11 811+59554100i 129+100620900i 257+30412300i 2021-01-12 849+46270700i 129+ 91951100i 251+26449900i 2021-01-13 854+33312500i 131+ 88636800i 252+19528900i 2021-01-14 845+31266300i 129+ 90221800i 246+29739400i 2021-01-15 826+38777600i 127+111598500i 251+24942900i 2021-01-19 845+25294000i 128+ 90296400i 261+27887200i

On Wed, Jan 20, 2021 at 3:07 PM Robin Hankin notifications@github.com wrote:

I hadn't appreciated that you wanted to deal with groups of columns as a unit. I have been toying with the idea of generalizing the format of an onionmat [which is a two element list, the first being a data vector and the second an integer matrix used for indexing] so that the data vector is a list and the indexing is done by an array. Would this be interesting?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

-- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com