R: transpose a series to a matrix with ignoring remains - r

Matlab can do this task. I cannot get it right so far by using matrix(), t(), and reShape().
My intention is to transpose a series to a matrix of fixed 10 rows and the number of column varies based on the length of the data series. If these are some remains left, they can be discarded.
For example:
Row #1 1 2 3 4
Row #2 5 6 7 8
Row #3 9 10 11 12
Row #4 13 14 15 16
Row #5 17 18 19 20
Row #6 21 22 23 24
Row #7 25 26 27 28
Row #8 29 30 31 32
Row #9 33 34 35 36
Row #10 37 38 39 40
If there are any remains left (i.e, 41~49), these data can be just discarded.
Any suggestions?

This is what I think you are asking for. A vector of arbitrary length and data. To be turned into a matrix with nrow 10 and ncol based on data length.
#your series of arbitrary length
data = 1:49
#calculate number of columns based on length
col = as.integer(length(data)/10)
#max index
maxIndx = 10*col
#create and transpose matrix
yourMtx = t(matrix(data[0:maxIndx],col,10))
#your matrix
> [,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
[4,] 13 14 15 16
[5,] 17 18 19 20
[6,] 21 22 23 24
[7,] 25 26 27 28
[8,] 29 30 31 32
[9,] 33 34 35 36
[10,] 37 38 39 40
#create reverse matrix
revMtx = yourMtx[,rev(seq_len(ncol(yourMtx)))]
#reverse matrix
> [,1] [,2] [,3] [,4]
[1,] 4 3 2 1
[2,] 8 7 6 5
[3,] 12 11 10 9
[4,] 16 15 14 13
[5,] 20 19 18 17
[6,] 24 23 22 21
[7,] 28 27 26 25
[8,] 32 31 30 29
[9,] 36 35 34 33
[10,] 40 39 38 37

If I understand your question correctly, this looks to be an approach you could use.
# generate my series
myseries <- 1:49
# specify number of columns and rows
ncols <- 4
nrows <- 10
# create a matrix with the first ncols*nrows elements and fill by row
mymatrix <- matrix(myseries[1:(ncols*nrows)],
ncol = ncols, nrow = nrows, byrow = TRUE)
mymatrix
[,1] [,2] [,3] [,4]
[1,] 1 2 3 4
[2,] 5 6 7 8
[3,] 9 10 11 12
[4,] 13 14 15 16
[5,] 17 18 19 20
[6,] 21 22 23 24
[7,] 25 26 27 28
[8,] 29 30 31 32
[9,] 33 34 35 36
[10,] 37 38 39 40

Related

How to select the n lowest values, n lowest values excluding the lowest, etc. in a for loop in R?

In R, I want to make a for loop in which I want to select the n lowest values, then the n lowest values excluding lowest value, then the n lowest values excluding the 2 lowest values etc.
Here's an example to clarify:
set.seed(1)
x <- round(rnorm(10,20,15))
n <- 4
I want to get:
7 8 11 15
8 11 15 23
11 15 23 25
15 23 25 27
23 25 27 29
25 27 29 31
27 29 31 44
I tried the following code, but then I do not get the last row (does not include last/highest value). I could get this by adding another code line in the for loop, but was wondering whether this could be done more efficient.
y <- matrix(data=NA, nrow=length(x)+1-n, ncol=n)
for (i in 1:(length(x)-n)) {y[i,] <- sort(x)[i:(i+n-1)]}
Thanks
set.seed(1)
x <- round(rnorm(10,20,15))
n <- 4
Get the pattern:
rbind(sort(x)[1:4], sort(x)[2:5], sort(x)[3:6], sort(x)[4:7], sort(x)[5:8], sort(x)[6:9], sort(x)[6:9], sort(x)[7:10])
Now, use dynamic programming in R to finish (in the general case):
matrix(c( sapply(1:(length(x)+1-n), function(i) sort(x)[i:(i+3)] )),nrow=length(x)+1-n, byrow=TRUE)
[,1] [,2] [,3] [,4]
[1,] 7 8 11 15
[2,] 8 11 15 23
[3,] 11 15 23 25
[4,] 15 23 25 27
[5,] 23 25 27 29
[6,] 25 27 29 31
[7,] 27 29 31 44
The most perfect one:
t(sapply(1:(length(x)+1-n), function(i) sort(x)[i:(i+3)] ))
[,1] [,2] [,3] [,4]
[1,] 7 8 11 15
[2,] 8 11 15 23
[3,] 11 15 23 25
[4,] 15 23 25 27
[5,] 23 25 27 29
[6,] 25 27 29 31
[7,] 27 29 31 44
Note that sapply provides columnwise outputs, hence a transpose finished the inconvinience.
Note to Rob: Apply family (apply, mapply, sapply, tapply etc.) overrides for. Hence, you should use this family as long as possible.

rbind() in mapply() results different output in R

Iam new to R and trying to understand mapply() behaviour.
I have two dataframes k1 and k2.
When I use rbind(k1,k2) it appends k2 at the bottom of k1.
But when I use it along mapply(rbind,k1,k2), it takes 1row from k1 and other from k2 and appends.
Is it possible to append k1 after k2 using mapply().
Can you also explain when is mapply() used in real-time scenario.
> k1 <- data.frame(x1 = 1:10, x2 = 11:20)
> k2 <- data.frame(x1= 21:30, x2 = 31:40)
>
> rbind(k1,k2)
x1 x2
1 1 11
2 2 12
3 3 13
4 4 14
5 5 15
6 6 16
7 7 17
8 8 18
9 9 19
10 10 20
11 21 31
12 22 32
13 23 33
14 24 34
15 25 35
16 26 36
17 27 37
18 28 38
19 29 39
20 30 40
> mapply(rbind,k1,k2)
x1 x2
[1,] 1 11
[2,] 21 31
[3,] 2 12
[4,] 22 32
[5,] 3 13
[6,] 23 33
[7,] 4 14
[8,] 24 34
[9,] 5 15
[10,] 25 35
[11,] 6 16
[12,] 26 36
[13,] 7 17
[14,] 27 37
[15,] 8 18
[16,] 28 38
[17,] 9 19
[18,] 29 39
[19,] 10 20
[20,] 30 40
I want the output using mapply() function like the first output.
mapply applies the function to the first element of the first input and the first element of the second input, second element of the first input and second element of the second input, etc. So since k1 and k2 are both dataframes, mapply(rbind, k1, k2) would rbind first column of k1 to first column of k2, and so on... It then simplifies the output to a matrix.
If you want to use mapply in this fashion, you would want to use the non-simplified version (mapply(f, ..., SIMPLIFY = FALSE)) and supply single element lists, this forces mapply to rbind the dataframes and not simplify the output list:
mapply(rbind, list(k1), list(k2), SIMPLIFY = FALSE)
This gives you the correct binding, but results in a list of one element.
[[1]]
x1 x2
1 1 11
2 2 12
3 3 13
4 4 14
5 5 15
6 6 16
7 7 17
8 8 18
9 9 19
10 10 20
11 21 31
12 22 32
13 23 33
14 24 34
15 25 35
16 26 36
17 27 37
18 28 38
19 29 39
20 30 40
The following would give you the same result as rbind(k1, k2):
unlist(mapply(rbind, list(k1), list(k2), SIMPLIFY = FALSE))
As noted by #Mako212, Reduce and do.call might be better tools to use in this case.
It sounds like you may be misusing mapply()
Instead, create a list of the data frames:
dfList <- list(k1,k2)
And rbind using Reduce like so:
Reduce(rbind, dfList)
And another way:
do.call("rbind",dfList)

How to lag a matrix in R

I want to know the command in R to lag a matrix.
I have defined x as:
> (x <- matrix(1:50, 10, 5))
[,1] [,2] [,3] [,4] [,5]
[1,] 1 11 21 31 41
[2,] 2 12 22 32 42
[3,] 3 13 23 33 43
[4,] 4 14 24 34 44
[5,] 5 15 25 35 45
[6,] 6 16 26 36 46
[7,] 7 17 27 37 47
[8,] 8 18 28 38 48
[9,] 9 19 29 39 49
[10,] 10 20 30 40 50
I want create l.x:
[,1] [,2] [,3] [,4] [,5]
[1,] NA NA NA NA NA
[2,] 1 11 21 31 41
[3,] 2 12 22 32 42
[4,] 3 13 23 33 43
[5,] 4 14 24 34 44
[6,] 5 15 25 35 45
[7,] 6 16 26 36 46
[8,] 7 17 27 37 47
[9,] 8 18 28 38 48
[10,] 9 19 29 39 49
lag will coerce your object to a time-series (ts class to be specific) and only shifts the time index. It does not change the underlying data.
You need to manually lag the matrix yourself by adding rows of NA at the beginning and removing the same number of rows at the end. Here's an example of a function that does just that:
lagmatrix <- function(x, k) {
# ensure 'x' is a matrix
stopifnot(is.matrix(x))
if (k == 0)
return(x)
na <- matrix(NA, nrow=abs(k), ncol=ncol(x))
if (k > 0) {
nr <- nrow(x)
# prepend NA and remove rows from end
rbind(na, x[-((nr-k):nr),])
} else {
# append NA and remove rows from beginning
rbind(x[-1:k,], na)
}
}
Or you can use a lag function that does what you expect. For example, xts::lag.xts.
> xts::lag.xts(x)
[,1] [,2] [,3] [,4] [,5]
[1,] NA NA NA NA NA
[2,] 1 11 21 31 41
[3,] 2 12 22 32 42
[4,] 3 13 23 33 43
[5,] 4 14 24 34 44
[6,] 5 15 25 35 45
[7,] 6 16 26 36 46
[8,] 7 17 27 37 47
[9,] 8 18 28 38 48
[10,] 9 19 29 39 49
> is.matrix(xts::lag.xts(x))
[1] TRUE
Here is one manual method in base R with head and rbind:
rbind(NA, head(x, 9))
[,1] [,2] [,3] [,4] [,5]
[1,] NA NA NA NA NA
[2,] 1 11 21 31 41
[3,] 2 12 22 32 42
[4,] 3 13 23 33 43
[5,] 4 14 24 34 44
[6,] 5 15 25 35 45
[7,] 6 16 26 36 46
[8,] 7 17 27 37 47
[9,] 8 18 28 38 48
[10,] 9 19 29 39 49
More generally, as noted by #akrun, head(., -1) will work for any sized matrix:
rbind(NA, head(x, -1))
We can use apply
library(dplyr)
apply(x, 2, lag)
# [,1] [,2] [,3] [,4] [,5]
# [1,] NA NA NA NA NA
# [2,] 1 11 21 31 41
# [3,] 2 12 22 32 42
# [4,] 3 13 23 33 43
# [5,] 4 14 24 34 44
# [6,] 5 15 25 35 45
# [7,] 6 16 26 36 46
# [8,] 7 17 27 37 47
# [9,] 8 18 28 38 48
#[10,] 9 19 29 39 49
0r
rbind(NA, x[-nrow(x),])
# [,1] [,2] [,3] [,4] [,5]
# [1,] NA NA NA NA NA
# [2,] 1 11 21 31 41
# [3,] 2 12 22 32 42
# [4,] 3 13 23 33 43
# [5,] 4 14 24 34 44
# [6,] 5 15 25 35 45
# [7,] 6 16 26 36 46
# [8,] 7 17 27 37 47
# [9,] 8 18 28 38 48
#[10,] 9 19 29 39 49
Below is a pure dplyr solution without the need for apply. Only annoyance here is that it needs to be converted to a data.frame to work.
library(dplyr)
x %>% as.data.frame %>% mutate_each( funs(lag))

R reverse some rows in a matrix

I have a 60 column matrix, and I want to reverse the some of its rows.
I came across the following two ways to do this:
#rtr is an integer vectors with the indices of the rows I want to reverse
matrix[rtr,]<-matrix[rtr,(ncol(matrix):1]
and
matrix[rtr,]<-rev(mat[rtr,])
Are these two implementations expected to produce the same result, or
are there some differences between them?
Thanks in advance
This seems to be a pretty easy thing to test
mm <- matrix(1:(6*7), ncol=6)
m2 <- m1 <- mm
rtr<-c(1,6,7)
m1[rtr,]<-m1[rtr, ncol(m1):1]
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 36 29 22 15 8 1
# [2,] 2 9 16 23 30 37
# [3,] 3 10 17 24 31 38
# [4,] 4 11 18 25 32 39
# [5,] 5 12 19 26 33 40
# [6,] 41 34 27 20 13 6
# [7,] 42 35 28 21 14 7
m2[rtr,]<-rev(m2[rtr,])
# [,1] [,2] [,3] [,4] [,5] [,6]
# [1,] 42 35 28 21 14 7
# [2,] 2 9 16 23 30 37
# [3,] 3 10 17 24 31 38
# [4,] 4 11 18 25 32 39
# [5,] 5 12 19 26 33 40
# [6,] 41 34 27 20 13 6
# [7,] 36 29 22 15 8 1
We can see they produce different output. The latter changes the order of the rows as well rather than just reversing them "in place"

Select rows without missing values in R

I am a new user to R and for loop. I am trying to take sampling from data and check to see if there is a colinear column. I want to record in that iteration that the colinear column exists and record it in the vector (baditr). Also, I would like to print a line indicating that "colinearity is at iteration i". Then I would like the code to jump to the second iteration and continue running. For each iteration, I would like the code to save the sum of the columns in the corresponding row of the matrix.
My problem is that I am getting an NA for the bad iterations. My intent is for bad iterations to not be included in my matrix at all. Here is my code:
a0=rep(1,40)
a=rep(0:1,20)
b=c(rep(1,20),rep(0,20))
c0=c(rep(0,12),rep(1,28))
c1=c(rep(1,5),rep(0,35))
c2=c(rep(1,8),rep(0,32))
c3=c(rep(1,23),rep(0,17))
da=matrix(cbind(a0,a,b,c0,c1,c2,c3),nrow=40,ncol=7)
sing <- function(nrw){
sm <- matrix(NA,nrow=nrw,ncol=ncol(da))
baditr <- NULL
for(i in 1:nrw){
ind <- sample(1:nrow(da), nrow(da),replace =TRUE)
smdat <- da[ind,]
evals <- eigen(crossprod(smdat))$values
if(any(abs(evals) < 1e-7)){
baditr <- c(baditr,i)
cat("singularity occurs at", paste(i),"\n")
next
}
sm[i,] <- apply(smdat,2,sum)
}
return(sm)
}
sing(20)
I will get the following output:
singularity occurs at 9
singularity occurs at 13
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 40 23 22 25 5 8 26
[2,] 40 20 18 30 4 7 22
[3,] 40 19 24 28 6 7 25
[4,] 40 19 22 30 6 9 26
[5,] 40 12 26 26 8 13 30
[6,] 40 17 16 27 7 10 19
[7,] 40 20 17 33 3 5 19
[8,] 40 22 19 28 4 9 23
[9,] NA NA NA NA NA NA NA
[10,] 40 21 24 28 3 6 27
[11,] 40 21 16 31 2 4 22
[12,] 40 21 21 26 3 6 23
[13,] NA NA NA NA NA NA NA
[14,] 40 18 16 29 2 7 22
[15,] 40 24 18 30 6 9 21
[16,] 40 23 18 29 4 8 21
[17,] 40 17 25 25 3 8 29
[18,] 40 22 28 23 9 14 30
[19,] 40 25 23 25 7 11 30
[20,] 40 20 23 27 7 10 26
I would like my matrix to look like this:
singularity occurs at 9
singularity occurs at 13
[,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,] 40 23 22 25 5 8 26
[2,] 40 20 18 30 4 7 22
[3,] 40 19 24 28 6 7 25
[4,] 40 19 22 30 6 9 26
[5,] 40 12 26 26 8 13 30
[6,] 40 17 16 27 7 10 19
[7,] 40 20 17 33 3 5 19
[8,] 40 22 19 28 4 9 23
[10,] 40 21 24 28 3 6 27
[11,] 40 21 16 31 2 4 22
[12,] 40 21 21 26 3 6 23
[14,] 40 18 16 29 2 7 22
[15,] 40 24 18 30 6 9 21
[16,] 40 23 18 29 4 8 21
[17,] 40 17 25 25 3 8 29
[18,] 40 22 28 23 9 14 30
[19,] 40 25 23 25 7 11 30
[20,] 40 20 23 27 7 10 26
As a fail safe, I would also appreciate any information you may have on saving a certain number of iterations to a file (for example, 50 iterations), which I can override once the next number of iterations is produced. Meaning, I save the first 50 iterations to a file and then once the second round of 50 iterations is produced, they override the first round and as a result, my file now has 100 iterations.
Sorry for the long post. But thanks in advance.
Before you return sm, you can filter out the rows with NA values by using complete.cases(). It would look something like sm[complete.cases(sm),]. The function returns a logical vector of TRUE/FALSE values, which forces R to not return those values with FALSE.
Also, it doesn't look like you are doing anything with baditers after defining it.I can comment out all lines referring to baditers and your function seems to work just fine...maybe it's a legacy from an older iteration of your code?
Update
Here's your updated function using complete.cases(). Note I also commented out everything related to baditr to illustrate that it's not doing anything currently in your code.
sing <- function(nrw){
sm <- matrix(NA,nrow=nrw,ncol=ncol(da))
#baditr <- NULL
for(i in 1:nrw){
ind <- sample(1:nrow(da), nrow(da),replace =TRUE)
smdat <- da[ind,]
evals <- eigen(crossprod(smdat))$values
if(any(abs(evals) < 1e-7)){
#baditr <- c(baditr,i)
cat("singularity occurs at", paste(i),"\n")
next
}
sm[i,] <- apply(smdat,2,sum)
}
return(sm[complete.cases(sm),])
}
Now let's run the function, I'm wrapping dim() around the function call which will tell us the #rows and #columns of the resulting object:
> dim(sing(20))
singularity occurs at 6
[1] 19 7
So one singularity and a matrix of 19 rows and 7 columns, am I missing something?
As to your other question about writing things out, are you aware of the append parameter to write.table() and friends? The help page tells us that If TRUE, the output is appended to the file. If FALSE, any existing file of the name is destroyed.
Update 2
Here's an example using append = TRUE in write.table()
#Matrix 1 definition and write to file
x <- matrix(1:9, ncol = 3)
write.table(x, "out.txt", sep = "\t", col.names = TRUE, row.names = FALSE)
#Matrix 2 definition and write to same file with append = TRUE
x2 <- matrix(10:18, ncol = 3)
write.table(x2, "out.txt", sep = "\t", col.names = FALSE, row.names = FALSE, append = TRUE)
#read consolidated data back in to check if it's right
x3 <- read.table("out.txt", header = TRUE)
Results in
V1 V2 V3
1 1 4 7
2 2 5 8
3 3 6 9
4 10 13 16
5 11 14 17
6 12 15 18

Resources