This question already has answers here:
Moving columns within a data.frame() without retyping
(17 answers)
Closed 8 years ago.
i would like to move columns in a matrix by one to the right.
Input <- data.frame(read.csv2 ....)
The matrix looks like:
1 2 3 4
1 2 3 4
1 2 3 4
and should be like:
4 1 2 3
4 1 2 3
4 1 2 3
I googled it but i couldn't find anything.
thanks for your help!!!
This looks like pretty good Moving columns within a data.frame() without retyping
Although the answer in comments works for a one-column shift to the right, its fiddly to extend that approach to other shifts and directions.
It boils down to generating the vector of the order of columns that you want to return, and then subsetting columns.
So your original Q boils down to generating c(4,1,2,3). There's a handy function in the magic package that can do this:
> install.packages("magic") # if you dont have it
> magic::shift(1:4,1)
[1] 4 1 2 3
So:
> Data[,magic::shift(1:ncol(Data),1)]
[,1] [,2] [,3] [,4]
[1,] 13 1 5 9
[2,] 14 2 6 10
[3,] 15 3 7 11
[4,] 16 4 8 12
answers your original question. This is then easy to extend to shifts by more than one, or negative (leftward) shifts:
> Data[,magic::shift(1:ncol(Data),-2)]
[,1] [,2] [,3] [,4]
[1,] 9 13 1 5
[2,] 10 14 2 6
[3,] 11 15 3 7
[4,] 12 16 4 8
Of course the right way is now to create matrix shift function:
> mshift = function(m,n=1){m[,magic::shift(1:ncol(m),n)]}
which you can check:
> mshift(Data,1)
[,1] [,2] [,3] [,4]
[1,] 13 1 5 9
[2,] 14 2 6 10
[3,] 15 3 7 11
[4,] 16 4 8 12
Related
How to print out some of row and some of column in R?
mat <- matrix(c(2,5,7,2,5,3,6,8,1,1,1,1,2,2,3),nrow=3,ncol=5)
mat
Here is my original matrix.
2 2 6 1 2
5 5 8 1 2
7 3 1 1 3
I have to make a matrix like this.
2 2 6 1 2 13
5 5 8 1 2 21
7 3 1 1 3 15
14 10 15 3 7 49
new row is the sum of original matrix row elements, new column is the sum of original column matrix elements.
49 is the sum of original matrix elements.
I'm trying to use apply, but apply just print out sum of elements individually.
How can I do that?
how to solve this problem?
what method do I have to use?
You can use addMargins(mat) as suggested by akrun, or, if you want a standard matrix result, you can do:
mat2 <- cbind(mat, rowSums(mat))
rbind(mat2, colSums(mat2))
#> [,1] [,2] [,3] [,4] [,5] [,6]
#> [1,] 2 2 6 1 2 13
#> [2,] 5 5 8 1 2 21
#> [3,] 7 3 1 1 3 15
#> [4,] 14 10 15 3 7 49
If there were a matrix, example:
m <- matrix(c(1:4), nrow = 4, ncol=4)
how would I go about multiplying only the odd rows by an arbitrary scalar while still keeping the even rows in the same place and the same value?
In this example, the matrix with only odd rows being multiplied by two would become:
1 1 1 1 2 2 2 2
2 2 2 2 2 2 2 2
3 3 3 3 ----> 6 6 6 6
4 4 4 4 4 4 4 4
You can pass bool vector to matrix, and if it divisible with number of rows r will replicate it.
mat <- matrix(1:4,4,4)
mat[c(TRUE,FALSE),] <- mat[c(TRUE,FALSE),] * 2
[,1] [,2] [,3] [,4]
[1,] 2 2 2 2
[2,] 2 2 2 2
[3,] 6 6 6 6
[4,] 4 4 4 4
Here is a base R code using diag() + rep()
diag(rep(c(2,1),nrow(mat)/2))%*% mat
such that
> diag(rep(c(2,1),nrow(mat)/2))%*% mat
[,1] [,2] [,3] [,4]
[1,] 2 2 2 2
[2,] 2 2 2 2
[3,] 6 6 6 6
[4,] 4 4 4 4
I am trying to learn the piping function (%>%).
When trying to convert from this line of code to another line it does not work.
---- R code -- original version -----
set.seed(1014)
replicate(6,sample(1:8))
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 3 7 4 5 1
[2,] 2 8 4 2 4 2
[3,] 5 4 8 5 8 5
[4,] 3 1 2 1 1 7
[5,] 4 6 3 7 7 3
[6,] 6 5 1 3 3 8
[7,] 8 7 5 8 6 6
[8,] 7 2 6 6 2 4
---- R code - recoded with the pipe ----
> sample(1:8) %>% replicate(6,.)
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 7 7 7 7 7 7
[2,] 3 3 3 3 3 3
[3,] 2 2 2 2 2 2
[4,] 1 1 1 1 1 1
[5,] 5 5 5 5 5 5
[6,] 4 4 4 4 4 4
[7,] 8 8 8 8 8 8
[8,] 6 6 6 6 6 6
Notice that when using pipes, the sampling does not work giving me
the same vector across.
That's to be expected. replicate expects an expression, but when using the pipe operator as is you just paste the result of the call to sample() to replicate. So you get 6 times the same result.
You have to use quote() to pass the expression to replicate instead of the result, but you shouldn't forget to evaluate each of the repetitions of that expression.
quote(sample(c(1:10,-99),6,rep=TRUE)) %>%
replicate(6, .) %>%
sapply(eval)
Gives:
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 5 2 10 10 9 2
[2,] 4 3 1 3 -99 1
[3,] 10 2 3 8 2 4
[4,] -99 1 6 2 10 3
[5,] 8 -99 1 9 4 6
[6,] 4 10 8 1 -99 8
What happens here:
the piping sends and expression to replicate without evaluating it.
replicate replicates that expression and returns a list with 6 times that expression but without evaluating it.
sapply(eval) goes through the list and executes each expression in that list.
In your previous question (i.e. when using data.frame), you could have done eg:
quote(sample(c(1:10,-99),6,rep=TRUE)) %>%
replicate(6, .) %>%
data.frame
Now the function data.frame would force the expressions to be executed, but you also end up with terrible variable names, i.e. the expression itself.
If you want to learn more about the issues here, you'll have to dive into what is called "lazy evaluation" and how that is dealt with exactly by the pipe operator. But in all honesty, I really don't see any advantage of using the pipe operator in this case. It's not even more readable.
As per Frank's comment: You can use a mixture of piping and nesting of functions to avoid the sapply. But for that, you have to contain the nested functions inside a code block or the pipe operator won't process it correctly:
quote(sample(c(1:10,-99),6,rep=TRUE)) %>% {
replicate(6, eval(.)) }
Very interesting, but imho not really useful...
Can matrix row and column names be set to defaults (e.g., [1,], [2,]... [,1], [,2]...) in R?
For example, is there a quick way to transform a matrix like this
x1 <- matrix(1:9,nrow=3,ncol=3,dimnames=list(1:3,letters[1:3]))
> x1
a b c
1 1 4 7
2 2 5 8
3 3 6 9
into this
> x1
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
You're looking for dimnames<-:
dimnames(x1) <- NULL
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
You can see the help file by typing ?dimnames. It is also linked from ?matrix.
I have a matrix called m as follows
> m<-matrix(1:15,3,5)
> m
[,1] [,2] [,3] [,4] [,5]
[1,] 1 4 7 10 13
[2,] 2 5 8 11 14
[3,] 3 6 9 12 15
I want to remove the first column of this matrix. Within a function I pass a value called j, which is always 1 less than the number of columns in m (In this example j is 4).
Therefore I used the following code
>m[,2:4+1]
[,1] [,2] [,3]
[1,] 7 10 13
[2,] 8 11 14
[3,] 9 12 15
But it is giving only the last 3 columns. Then I changed the code as follows
>m[,2:(4+1)]
This time I had the correct output.
Also it is giving the same output for following code as well
> m[,1:4+1]
Somebody please explain me how the following codes work?
>m[,2:4+1]
>m[,1:4+1]
: has higher precedence than +, therefore 2:4+1 gets interpreted at (2:4)+1 which is the same as 3:5:
2:4+1
[1] 3 4 5
Similarly, 1:4+1 gets interpreted as 2:5:
1:4+1
[1] 2 3 4 5
To remove columns in a matrix, its probably easier to use the negative subscript input to [:
m[,-1]
[,1] [,2] [,3] [,4]
[1,] 4 7 10 13
[2,] 5 8 11 14
[3,] 6 9 12 15