system is computationally singular error - r

I am using fastICA package in r. In this package, I am using fastICA function, which have some parameters. If I set n.comp to 2, that works fine, but if I set this parameter to 3 or more in this function:
ica<-fastICA(datalist,n.comp=3)
datalist is here a matrix with 20 rows and 4 columns:
[,1] [,2] [,3] [,4]
[1,] 567.00 324.225 281.0889 538.25
[2,] 557.75 317.500 269.5556 529.15
[3,] 543.75 309.900 264.5778 515.95
[4,] 557.00 316.225 265.0889 528.25
[5,] 538.25 307.750 266.6667 510.95
[6,] 531.25 301.025 250.0222 503.70
[7,] 545.00 311.800 270.9333 517.40
[8,] 550.00 316.925 284.3778 522.65
[9,] 514.75 290.300 235.6000 487.75
[10,] 518.00 293.800 245.1556 491.20
[11,] 553.75 318.125 281.6667 526.00
[12,] 563.50 325.925 297.2667 535.75
[13,] 540.00 303.300 241.1556 511.40
[14,] 546.00 310.350 261.6444 517.90
[15,] 567.25 324.425 281.4889 538.50
[16,] 577.75 330.125 285.2222 548.40
[17,] 560.75 317.425 262.3778 531.60
[18,] 570.00 323.925 272.8222 540.65
[19,] 569.00 324.700 278.8444 540.00
[20,] 565.50 324.150 284.1333 537.00
I am getting this error:
Error in solve.default(w %*% t(w)) :
system is computationally singular: reciprocal condition number = 1.16873e-16
could you please say me why I am getting this error and how can I solve it?

In solve(), use a smaller tolerance, like solve(..., tol = 1e-17).
This should be fine since you get reciprocal condition number = 1.16873e-16.
More info in the help file and this related question.

Related

r igraph - how does plot() read the layout matrix?

My question is related to this one here, which unfortunately has not been responded. I'm trying to automatically annotate text next to highlighted communities on a plot. An intermediate step is to understand how nodes are placed on a plot.
G <- make_graph('zachary')
l <- layout_with_fr(G)
l
A layout is a matrix with rows representing nodes and columns representing the x and y plot parameters.
[,1] [,2]
[1,] 2.8510654 -2.2404898
[2,] 2.7183497 -1.1815130
[3,] 3.1429205 0.1117099
[4,] 1.5585372 -1.0743325
[5,] 2.2808632 -4.2035479
[6,] 2.1698198 -5.0526766
[7,] 1.4938068 -4.6975884
[8,] 1.9710816 -1.4672218
[9,] 3.5407035 0.5407852
[10,] 2.2222909 1.9079805
[11,] 3.0784642 -4.5828448
[12,] 4.4115351 -4.1057462
[13,] 0.6002378 -2.2432049
[14,] 2.5010525 -0.1563341
[15,] 4.8914673 4.1417759
[16,] 3.2053338 3.9212694
[17,] 1.1825200 -6.4099021
[18,] 3.7155897 -2.8354432
[19,] 3.8272351 4.2660906
[20,] 3.8636487 -0.5671906
[21,] 2.7302411 3.3998888
[22,] 1.6084374 -2.7407388
[23,] 4.3432855 3.8101278
[24,] 5.9392042 2.2364929
[25,] 6.9980077 0.2389222
[26,] 7.1608499 1.1360134
[27,] 6.0171481 4.0279067
[28,] 5.4996627 1.0367163
[29,] 4.4961257 0.9434659
[30,] 5.5987563 3.2314488
[31,] 2.9958404 1.2022317
[32,] 5.1188900 0.2919268
[33,] 4.1088296 2.5032294
[34,] 4.1686534 2.1339884
But the x, y coordinates of the plot go from -1 to 1, unlike the min-max coordinates in the layout matrix. So how is plot(G, layout = l) reading the layout matrix?
The according to the source, the plot method for objects of class igraph simply rescales the matrix from -1 to 1.
library(igraph)
set.seed(3)
l <- layout_with_fr(G)
[,1] [,2]
[1,] -2.283 0.658
[2,] -1.289 -0.108
[3,] 0.146 1.012
[4,] -1.523 1.601
#... with 30 more rows.
plot(G,layout = l)
maxs <- apply(l, 2, max)
mins <- apply(l, 2, min)
ll <- scale(l, center=(maxs+mins)/2, scale=(maxs-mins)/2)
ll
[,1] [,2]
[1,] -0.2422 -0.1051
[2,] -0.0704 -0.3821
[3,] 0.1775 0.0228
[4,] -0.1108 0.2357
#... with 30 more rows.
plot(G,layout = ll)
Note that the actual rescaling is performed with igraph::norm_coords:
igraph::norm_coords(l)
[,1] [,2]
[1,] -0.2422 -0.1051
[2,] -0.0704 -0.3821
[3,] 0.1775 0.0228
[4,] -0.1108 0.2357
#... with 30 more rows.

How to create a date sequence for 10 years with 16 Day interval with each year starts with 1st January

Following code create a date sequence of 10 years with 16 Day interval.
library(chron)
seq.dates("01/01/2008","12/31/2017", 16)
Output
[1] 01/01/08 01/17/08 02/02/08 02/18/08 03/05/08 03/21/08 04/06/08 04/22/08 05/08/08
[10] 05/24/08 06/09/08 06/25/08 07/11/08 07/27/08 08/12/08 08/28/08 09/13/08 09/29/08
[19] 10/15/08 10/31/08 11/16/08 12/02/08 12/18/08 **01/03/09** 01/19/09 02/04/09 02/20/09
[28] 03/08/09 03/24/09 04/09/09 04/25/09 05/11/09 ..........
........................
...........................
[208] 01/25/17 02/10/17 02/26/17 03/14/17 03/30/17 04/15/17 05/01/17 05/17/17 06/02/17
[217] 06/18/17 07/04/17 07/20/17 08/05/17 08/21/17 09/06/17 09/22/17 10/08/17 10/24/17
[226] 11/09/17 11/25/17 12/11/17 12/27/17
I want first entry for every year to be 1st January not the day which comes after 16 days from the last entry of previous year (BOLD entry in the example sequence) and subsequent entries accordingly.
A long way to do this would be creating date sequence for individual years separately then merging them in a single vector. I'm curious that is there any way to do this in a single line code.
How's this work for you. Uses sapply to pass a vector of starting points and then makes seq.dates do more limited sequences. The sapply function will simplify to an array if possible.
dates(sapply( seq.dates("01/01/2008", "01/01/2017", by="years") ,
function(x) seq.dates(x, to=x+365, by=16, length=23)))
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
[1,] 01/01/08 01/01/09 01/01/10 01/01/11 01/01/12 01/01/13 01/01/14 01/01/15
[2,] 01/17/08 01/17/09 01/17/10 01/17/11 01/17/12 01/17/13 01/17/14 01/17/15
[3,] 02/02/08 02/02/09 02/02/10 02/02/11 02/02/12 02/02/13 02/02/14 02/02/15
[4,] 02/18/08 02/18/09 02/18/10 02/18/11 02/18/12 02/18/13 02/18/14 02/18/15
[5,] 03/05/08 03/06/09 03/06/10 03/06/11 03/05/12 03/06/13 03/06/14 03/06/15
[6,] 03/21/08 03/22/09 03/22/10 03/22/11 03/21/12 03/22/13 03/22/14 03/22/15
[7,] 04/06/08 04/07/09 04/07/10 04/07/11 04/06/12 04/07/13 04/07/14 04/07/15
[8,] 04/22/08 04/23/09 04/23/10 04/23/11 04/22/12 04/23/13 04/23/14 04/23/15
[9,] 05/08/08 05/09/09 05/09/10 05/09/11 05/08/12 05/09/13 05/09/14 05/09/15
[10,] 05/24/08 05/25/09 05/25/10 05/25/11 05/24/12 05/25/13 05/25/14 05/25/15
[11,] 06/09/08 06/10/09 06/10/10 06/10/11 06/09/12 06/10/13 06/10/14 06/10/15
[12,] 06/25/08 06/26/09 06/26/10 06/26/11 06/25/12 06/26/13 06/26/14 06/26/15
[13,] 07/11/08 07/12/09 07/12/10 07/12/11 07/11/12 07/12/13 07/12/14 07/12/15
[14,] 07/27/08 07/28/09 07/28/10 07/28/11 07/27/12 07/28/13 07/28/14 07/28/15
[15,] 08/12/08 08/13/09 08/13/10 08/13/11 08/12/12 08/13/13 08/13/14 08/13/15
[16,] 08/28/08 08/29/09 08/29/10 08/29/11 08/28/12 08/29/13 08/29/14 08/29/15
[17,] 09/13/08 09/14/09 09/14/10 09/14/11 09/13/12 09/14/13 09/14/14 09/14/15
[18,] 09/29/08 09/30/09 09/30/10 09/30/11 09/29/12 09/30/13 09/30/14 09/30/15
[19,] 10/15/08 10/16/09 10/16/10 10/16/11 10/15/12 10/16/13 10/16/14 10/16/15
[20,] 10/31/08 11/01/09 11/01/10 11/01/11 10/31/12 11/01/13 11/01/14 11/01/15
[21,] 11/16/08 11/17/09 11/17/10 11/17/11 11/16/12 11/17/13 11/17/14 11/17/15
[22,] 12/02/08 12/03/09 12/03/10 12/03/11 12/02/12 12/03/13 12/03/14 12/03/15
[23,] 12/18/08 12/19/09 12/19/10 12/19/11 12/18/12 12/19/13 12/19/14 12/19/15
[,9] [,10]
[1,] 01/01/16 01/01/17
[2,] 01/17/16 01/17/17
[3,] 02/02/16 02/02/17
[4,] 02/18/16 02/18/17
[5,] 03/05/16 03/06/17
[6,] 03/21/16 03/22/17
[7,] 04/06/16 04/07/17
[8,] 04/22/16 04/23/17
[9,] 05/08/16 05/09/17
[10,] 05/24/16 05/25/17
[11,] 06/09/16 06/10/17
[12,] 06/25/16 06/26/17
[13,] 07/11/16 07/12/17
[14,] 07/27/16 07/28/17
[15,] 08/12/16 08/13/17
[16,] 08/28/16 08/29/17
[17,] 09/13/16 09/14/17
[18,] 09/29/16 09/30/17
[19,] 10/15/16 10/16/17
[20,] 10/31/16 11/01/17
[21,] 11/16/16 11/17/17
[22,] 12/02/16 12/03/17
[23,] 12/18/16 12/19/17
I was a bit surprised at this result since I thought the value would be a character matrix, but str shows it's a matrix of chron date elements. Can remove the apparent "matrix" (actually "dates" with a dimension attribute) structure with a call to c:
str(c(dates(sapply( seq.dates("01/01/2008", "01/01/2017", by="years") , function(x) seq.dates(x, to=x+365, by=16, length=23))) ))
'dates' num [1:230] 01/01/08 01/17/08 02/02/08 02/18/08 03/05/08 ...
- attr(*, "format")= chr "m/d/y"
- attr(*, "origin")= num [1:3] 1 1 1970

Apply - return results binded by rows not by columns

I have a function which applied on a vector of lenght 5 returns a matrix with 4 rows and 5 columns. Then I want to use apply() in order to call my function again on each row of the results matrix and obtain matrix with 16 (4*4) rows and 5 columns. Unfortuneately apply() combines the results into 4x20 matrix. How is it possible to change that without using lists?
matrixFromVector = function(x){
return(rbind(x*rnorm(1,1,.01),x*rnorm(1,1,.01),x*rnorm(1,1,.1),x*rnorm(1,1,.01))) }
a = matrixFromVector(1:5)
t(a)
[,1] [,2] [,3] [,4]
[1,] 1.008391 1.005974 1.077223 0.9865611
[2,] 2.016782 2.011947 2.154445 1.9731222
[3,] 3.025173 3.017921 3.231668 2.9596833
[4,] 4.033565 4.023894 4.308890 3.9462444
[5,] 5.041956 5.029868 5.386113 4.9328055
After applying my function to each row of a I would like to have
[1,] [2,] [3,] [4,] [5,]
[1,] 1.0242459 2.0484917 3.0727376 4.0969835 5.1212293
[2,] 0.9999314 1.9998629 2.9997943 3.9997257 4.9996572
[3,] 1.0836573 2.1673146 3.2509719 4.3346292 5.4182865
[4,] 1.0005137 2.0010275 3.0015412 4.0020550 5.0025687
[5,] 1.0314108 2.0628216 3.0942323 4.1256431 5.1570539
[6,] 0.9995248 1.9990496 2.9985744 3.9980992 4.9976239
[7,] 1.0908017 2.1816034 3.2724051 4.3632069 5.4540086
[8,] 0.9801833 1.9603667 2.9405500 3.9207333 4.9009166
[9,] 0.9697334 1.9394669 2.9092003 3.8789338 4.8486672
[10,] 0.8484190 1.6968380 2.5452570 3.3936760 4.2420950
[11,] 0.9120351 1.8240703 2.7361054 3.6481405 4.5601756
[12,] 0.9596908 1.9193816 2.8790724 3.8387632 4.7984540
[13,] 1.0226757 2.0453515 3.0680272 4.0907030 5.1133787
[14,] 1.0069771 2.0139543 3.0209314 4.0279085 5.0348857
[15,] 1.0748773 2.1497545 3.2246318 4.2995090 5.3743863
[16,] 0.9841864 1.9683728 2.9525592 3.9367456 4.9209319
Instead I got
apply(a,1,matrixFromVector)
[,1] [,2] [,3] [,4]
[1,] 1.0262524 1.0237143 1.074673 0.9885002
[2,] 0.9990472 1.0189053 1.062644 0.9965570
[3,] 0.9464976 0.8973152 1.138847 0.8639614
[4,] 1.0063561 1.0080947 1.080825 1.0033793
[5,] 2.0525048 2.0474286 2.149346 1.9770004
[6,] 1.9980944 2.0378107 2.125288 1.9931140
[7,] 1.8929952 1.7946303 2.277693 1.7279229
[8,] 2.0127121 2.0161895 2.161650 2.0067587
[9,] 3.0787573 3.0711429 3.224019 2.9655005
[10,] 2.9971416 3.0567160 3.187933 2.9896710
[11,] 2.8394929 2.6919455 3.416540 2.5918843
[12,] 3.0190682 3.0242842 3.242475 3.0101380
[13,] 4.1050097 4.0948572 4.298693 3.9540007
[14,] 3.9961888 4.0756214 4.250577 3.9862280
[15,] 3.7859905 3.5892607 4.555386 3.4558457
[16,] 4.0254242 4.0323789 4.323300 4.0135174
[17,] 5.1312621 5.1185715 5.373366 4.9425009
[18,] 4.9952359 5.0945267 5.313221 4.9827850
[19,] 4.7324881 4.4865759 5.694233 4.3198072
[20,] 5.0317803 5.0404736 5.404125 5.0168967
or
apply(a,1,function(x) t(matrixFromVector(x)))
[,1] [,2] [,3] [,4]
[1,] 1.0242459 0.9999314 1.0836573 1.0005137
[2,] 2.0484917 1.9998629 2.1673146 2.0010275
[3,] 3.0727376 2.9997943 3.2509719 3.0015412
[4,] 4.0969835 3.9997257 4.3346292 4.0020550
[5,] 5.1212293 4.9996572 5.4182865 5.0025687
[6,] 1.0314108 0.9995248 1.0908017 0.9801833
[7,] 2.0628216 1.9990496 2.1816034 1.9603667
[8,] 3.0942323 2.9985744 3.2724051 2.9405500
[9,] 4.1256431 3.9980992 4.3632069 3.9207333
[10,] 5.1570539 4.9976239 5.4540086 4.9009166
[11,] 0.9697334 0.8484190 0.9120351 0.9596908
[12,] 1.9394669 1.6968380 1.8240703 1.9193816
[13,] 2.9092003 2.5452570 2.7361054 2.8790724
[14,] 3.8789338 3.3936760 3.6481405 3.8387632
[15,] 4.8486672 4.2420950 4.5601756 4.7984540
[16,] 1.0226757 1.0069771 1.0748773 0.9841864
[17,] 2.0453515 2.0139543 2.1497545 1.9683728
[18,] 3.0680272 3.0209314 3.2246318 2.9525592
[19,] 4.0907030 4.0279085 4.2995090 3.9367456
[20,] 5.1133787 5.0348857 5.3743863 4.9209319
We can loop over the rows using lapply and then do this
do.call(rbind, lapply(seq_len(nrow(a)), function(i) matrixFromVector(a[i,])))
Or we place the output in a list using apply and then do the rbind
do.call(rbind, do.call(c, apply(a, 1, function(x) list(matrixFromVector(x)))))
why not
apply(t(a), 1, matrixFromVector)
or
apply(a, 2, matrixFromVector)

Extracting element from list of lists in R?

I have a list in the following format:
[[825]][[4]]
Each of the 4 inside list elements are different sized and dimensioned arrays:
[[1]]
[1] 0.02918644 0.03239657 0.03560670 0.03881683 0.04202696 0.04523709 0.04844722 0.05165735
[9] 0.05486748 0.05807761 0.06128774 0.06449787 0.06770800 0.07091813 0.07412827 0.07733840
[17] 0.08054853 0.08375866 0.08696879 0.09017892
[[2]]
[1] 0.7581078 0.7587820 0.7608009 0.7641538 0.7688234 0.7747857 0.7820113 0.7904655 0.8001093
[10] 0.8109003 0.8244816 0.8444896 0.8706241 0.9023530 0.9391094 0.9803280 1.0254709 1.0740433
[19] 1.1256013 1.1797536
[[3]]
[,1] [,2] [,3]
[1,] 0.4177711 0.34606863 2.361603e-01
[2,] 0.4345125 0.35491274 2.105747e-01
[3,] 0.4512540 0.36375685 1.849892e-01
[4,] 0.4679954 0.37260096 1.594036e-01
[5,] 0.4847369 0.38144507 1.338180e-01
[6,] 0.5014783 0.39028918 1.082325e-01
[7,] 0.5182198 0.39913329 8.264693e-02
[8,] 0.5349612 0.40797740 5.706137e-02
[9,] 0.5517027 0.41682150 3.147581e-02
[10,] 0.5684441 0.42566561 5.890257e-03
[11,] 0.6059978 0.39400216 0.000000e+00
[12,] 0.6497759 0.35022414 0.000000e+00
[13,] 0.6935539 0.30644612 0.000000e+00
[14,] 0.7373319 0.26266811 -2.408519e-18
[15,] 0.7811099 0.21889009 -6.394265e-19
[16,] 0.8248879 0.17511207 1.129666e-18
[17,] 0.8686659 0.13133405 2.898758e-18
[18,] 0.9124440 0.08755604 4.667850e-18
[19,] 0.9562220 0.04377802 6.436942e-18
[20,] 1.0000000 0.00000000 0.000000e+00
[[4]]
[,1]
[1,] 0.03849906
[2,] 0.04269549
[3,] 0.04680160
[4,] 0.05079714
[5,] 0.05466400
[6,] 0.05838658
[7,] 0.06195207
[8,] 0.06535055
[9,] 0.06857498
[10,] 0.07162115
[11,] 0.07433489
[12,] 0.07637498
[13,] 0.07776951
[14,] 0.07859245
[15,] 0.07893464
[16,] 0.07889032
[17,] 0.07854784
[18,] 0.07798443
[19,] 0.07726429
[20,] 0.07643877
I want to have 4 new lists, each with 825 elements:
[[4]][[825]]
For example, all the [[1]]'s, [[2]]'s etc. from the list of 825 should be combined.
What's the best way to do this? I've been trying to figure it out with some sort of apply..
First create an example list of lists:
big.lst <- lapply(1:825, function(x) rep(list(rnorm(10)), 4))
#check lengths
length(big.lst)
#[1] 825
unique(lengths(big.lst))
#[1] 4
Then lapply a subset over the big list. I chose 1:4 to create four new groups, but you can genralize with 1:length(big.lst[[1]]) as each sublist has the same length:
newlst <- lapply(1:4, function(x) lapply(big.lst, '[[', x))
#verify answer
length(newlst)
#[1] 4
unique(lengths(newlst))
#[1] 825

Select columns from nested lists in r

I have a list with 50 elements, and each element is a 21x2 matrix. I want to pull every first column so that I will be able to multiply the first column of each 21x2 matrix by another matrix.
Example data:
x<-replicate(50,cbind(rnorm(21,0,1),rnorm(21,1,1)))
x<-lapply(seq(dim(x)[3]), function(i) x[ , , i])
x[[1]]
[,1] [,2]
[1,] -1.00653872 1.2780327
[2,] -0.30442989 -0.6854457
[3,] -1.05715492 -0.3464085
[4,] 0.12005815 1.1885382
[5,] 0.93834177 1.4968285
[6,] 0.85975400 1.3084381
[7,] 0.91980222 -0.1580829
[8,] 0.35785346 1.7679500
[9,] -1.03510124 2.2865753
[10,] -0.74853505 0.5148834
[11,] -1.23582377 0.8514812
[12,] 0.69546075 0.8294420
[13,] 0.08527011 1.7080554
[14,] -0.81635552 0.7492530
[15,] 0.53826428 -0.3058294
[16,] 0.16545497 0.4415540
[17,] -0.27144363 0.8299643
[18,] 0.02851933 1.2673526
[19,] 1.86516449 0.3009744
[20,] -0.46998359 -0.3232826
[21,] -0.60222069 2.3836219
assign <- rep(c(0,1),times=c(10,11))
If I do
x[[1]][,1]*assign
I get what I'm looking for, but I want to be able to do this for all elements of x without a for-loop.
I tried
alt<-lapply(x, `[[`, 1)
but this only gives the first element of the first columns, whereas I want the whole vector.
Any suggestions?
Try using split to split each matrix by columns and take the first one
sapply(x, function(mat) split(mat, col(mat))[1])
You could also try simplify2array
simplify2array(x)[,1,]

Resources