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
Related
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
My problem is as follows and I have considered many derivations:
I have an array, say with dimensions dims = c(10000, 5, 2) - that is 10 rows, 5 columns and 2 subarrays.
I would like to be able to use the sample() function to sample a given proportion (say m) of rows in EACH subarray and move them BETWEEN subarrays.
So, say swap Row 5 subarray 1 with Row 10 of subarray 2 (see example below).
I asked a similar question
Moving rows between subarrays
and got some great help.
The solution is useful but restricted to random sampling of rows (meaning that not all subarrays will be sampled).
, , 1
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 4 3 4 4 3 4 5 2 4 4
[2,] 1 4 3 5 4 5 4 5 2 4
[3,] 1 5 2 1 1 2 1 4 5 1
[4,] 3 1 1 3 5 4 2 4 4 4
[5,] 3 2 5 1 2 2 5 5 4 3 <-- e.g., switch this row
[6,] 4 5 5 2 3 4 1 3 5 5
[7,] 5 5 5 5 1 4 3 1 2 5
[8,] 3 4 3 1 3 3 4 3 2 3
[9,] 1 1 3 2 4 4 1 4 2 3
[10,] 1 4 4 2 4 2 4 2 2 1
, , 2
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 5 5 1 1 5 2 1 4 3 1
[2,] 4 3 2 4 3 5 5 5 4 3
[3,] 2 4 1 1 4 2 2 2 3 4
[4,] 5 1 4 5 4 4 3 4 4 5
[5,] 1 5 5 4 3 3 5 2 2 2
[6,] 2 2 2 2 5 5 3 4 3 5
[7,] 5 2 1 1 2 5 3 4 4 2
[8,] 3 4 3 3 1 3 3 2 3 5
[9,] 2 1 4 4 3 2 4 5 5 2
[10,] 5 3 4 5 4 3 5 1 2 3 <-- with this row
In the above example, m = 0.10, that is 10% of the rows (1 row) in each subarray are sampled and then swapped.
Any ideas on how to force sample() to sample within ALL subarrays? Ideally, the number of rows in each subarray will be very large (10000 or more).
Though I have only included 2 subarrays, where a random row or rows swap(s) with a random row or rows in subarray 2 (dictated by m), I need a routine that is generalizable to k subarrays. So if k = 3, then sampling occurs within ALL subarrays and random rows are swapped with neighbouring subarrays.
So, a random row or rows in subarray 1 has equal chance of moving to either subarray 2 or subarray 3 (it doesn't matter which subarray rows go to, so long as they are always moving between subarrays. Then, the corresponding row or rows from subarray 2 or 3 will go to subarray 1.
The number of rows must remain constant. For example, there cannot be 11 rows in subarray 1 and only 9 in subarray 2 -- it has to be 10 and 10.
I don't know of any packages that will do this. The goal here is to simulate movement of animals.
Any ideas are greatly appreciated.
This is verbose and could be cleaned up, but should get you there.
set.seed(4)
x <- array(sample(1:10, 200, replace = T), dim = c(10, 10, 2))
nrows_x <- dim(x)[1]
proportion <- 0.10
idx <- sample(1:nrows_x, nrows_x * proportion)
rows_dim_1 <- x[idx, , 1]
rows_dim_2 <- x[idx, , 2]
x[idx, , 1] <- rows_dim_2
x[idx, , 2] <- rows_dim_1
I am trying to randomize a matrix such that each of the rows in each column are randomized individually so that in the final matrix there is no association between columns. I know that I need to use the sample() function and some sort of for(each column) loop, but I'm not exactly sure of how to go about doing it. Specifically, I am asking how to write a function that will loop through the columns of a matrix and randomize the rows of each column.
Edit: An example of what I'm trying to achieve
Original matrix:
X1 X2 X3
1 4 3 6
2 7 2 4
3 9 5 1
Sample desired output:
X1 X2 X3
1 7 3 1
2 4 5 6
3 9 2 4
As you can see, the rows in each column have been randomized separately.
If you have a matrix X, you can use apply() (ideal for matrix)
apply(X, 2, sample)
Example:
X <- matrix(1:25, 5)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 6 11 16 21
# [2,] 2 7 12 17 22
# [3,] 3 8 13 18 23
# [4,] 4 9 14 19 24
# [5,] 5 10 15 20 25
Apply the code above gives:
# [,1] [,2] [,3] [,4] [,5]
# [1,] 3 10 11 16 21
# [2,] 5 8 12 20 22
# [3,] 4 9 14 18 24
# [4,] 2 6 15 19 25
# [5,] 1 7 13 17 23
I did not set random seed via set.seed(), so you will get different result when you run it. But all you need to know is that: the result is random.
If you have a data frame X, you'd better use sapply()
sapply(X, sample)
You could use a for loop for each column.
Or you could use:
apply(x, 2, function(col) sample(col, replace=F))
For example suppose I have matrix A
x y z f
1 1 2 A 1005
2 2 4 B 1002
3 3 2 B 1001
4 4 8 C 1001
5 5 10 D 1004
6 6 12 D 1004
7 7 11 E 1005
8 8 14 E 1003
From this matrix I want to find the repeated values like 1001, 1005, D, 2 (in third column) and I also want to find their index (which row, or which position).
I am new to R!
Obviously it is possible to do with simple searching element by element by using a for loop, but I want to know, is there any function available in R for this kind of problem.
Furthermore, I tried using duplicated and unique, both functions are giving me the duplicated row number or column number, they are also giving me how many of them were repeated, but I can not search for whole matrix using both of them!
You can write a rather simple function to get this information. Though note that this solution works with a matrix. It does not work with a data.frame. A similar function could be written for a data.frame using the fact that the data.frame data structure is a subset of a list.
# example data
set.seed(234)
m <- matrix(sample(1:10, size=100, replace=T), 10)
find_matches <- function(mat, value) {
nr <- nrow(mat)
val_match <- which(mat == value)
out <- matrix(NA, nrow= length(val_match), ncol= 2)
out[,2] <- floor(val_match / nr) + 1
out[,1] <- val_match %% nr
return(out)
}
R> m
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 8 6 6 7 6 7 4 10 6 9
[2,] 8 6 6 3 10 4 5 4 6 9
[3,] 1 6 9 2 9 2 3 6 4 2
[4,] 8 6 7 8 3 9 9 4 9 2
[5,] 1 1 5 6 7 1 5 1 10 6
[6,] 7 5 4 7 8 2 4 4 7 10
[7,] 10 4 7 8 3 1 8 6 3 4
[8,] 8 8 2 2 7 5 6 4 10 4
[9,] 10 2 9 6 6 9 7 2 4 7
[10,] 3 9 9 4 2 7 7 2 9 6
R> find_matches(m, 8)
[,1] [,2]
[1,] 1 1
[2,] 2 1
[3,] 4 1
[4,] 8 1
[5,] 8 2
[6,] 4 4
[7,] 7 4
[8,] 6 5
[9,] 7 7
In this function, the row index is output in column 1 and the column index is output in column 2
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