Suppose I generate the following fictional matrix
mat <-matrix(1:12,3)
Now I would like to rearrange the order of the columns from 1:4 to 4:1
Manually I could do this by.
Z <- cbind(mat[,4],mat[,3],mat[,2],mat[,1])
Now when the matrix becomes large with for example 30 columns, doing this manually will be a tedious process.
Does anyone have a suggestion to rewrite the order of the columns with for example a loop?
We can use indexing i.e. create a sequence (:) from the last column index - ncol(mat) to 1 and use that as column index
mat[, ncol(mat):1]
Or with rev
mat[, rev(seq_len(ncol(mat)))]
Related
I have a big matrix (i.e 303*32). I want to create take out some columns and make a new matrix in R. I am unable to find any solution. Any help would be appreciated.
ads # Matrix of 303*32
new_mat <- matrix(c("speed","gaps","time")) # speed, gaps and times are names of cols which I am trying to exclude.
By using this code i am only getting cols and rows name .
If you want to exclude columns by name, you need something like:
new_mat <- ads[, !colnames(ads) %in% c("speed","gaps","time")]
I want to fill up certain values in a matrix by indexing a vector. It should be a simple loop
mat1[ i, as.numeric(index_vec[i]) ] = data[i,"price"]
I believe that is the only command I need for the loop because it fills the first row of the matrix properly if I put 1's where all of the i's are. Does anyone know very basic loops in R? I could be wrong, but I think its just a matter of syntax.
It's not an RStudio question but rather an R question. We would need to know the dimensions of mat1 and data and the lengths of index_vec to know if this makes any sense. It appears you may be coming from another language where everything is done with for-loops using indices. That's not always the best way to work with R. If the length of index_vec is the same as the number of rows of data and the values of as.numeric(index_vec) are above 1 and at or below the number of columns of mat1, then a modified version the suggestion above to use:
mat1[ 1 , as.numeric(index_vec) ] <- data[ ,"price"]
... should succeed as a column to row assignment. The lengths on the RHS need to equal the number of values assigned on the LHS. If my guess was wrong about the nature of index_vec and it's only a single number, then perhaps a column to column assignment:
mat1[ , as.numeric(index_vec) ] <- data[ ,"price"]
Then there is a third possibility as well. If you index_vec is a set of column locations and the implicit row locations go from 1 to length(index_vec) hten you could do this:
mat1[ cbind( seq_along(index_vec) , as.numeric(index_vec) ) ] <- data[ ,"price"]
I'm trying to update a bunch of columns by adding and subtracting SD to each value of the column. The SD is for the given column.
The below is the reproducible code that I came up with, but I feel this is not the most efficient way to do it. Could someone suggest me a better way to do this?
Essentially, there are 20 rows and 9 columns.I just need two separate dataframes one that has values for each column adjusted by adding SD of that column and the other by subtracting SD from each value of the column.
##Example
##data frame containing 9 columns and 20 rows
Hi<-data.frame(replicate(9,sample(0:20,20,rep=TRUE)))
##Standard Deviation calcualted for each row and stored in an object - i don't what this objcet is -vector, list, dataframe ?
Hi_SD<-apply(Hi,2,sd)
#data frame converted to matrix to allow addition of SD to each value
Hi_Matrix<-as.matrix(Hi,rownames.force=FALSE)
#a new object created that will store values(original+1SD) for each variable
Hi_SDValues<-NULL
#variable re-created -contains sum of first column of matrix and first element of list. I have only done this for 2 columns for the purposes of this example. however, all columns would need to be recreated
Hi_SDValues$X1<-Hi_Matrix[,1]+Hi_SD[1]
Hi_SDValues$X2<-Hi_Matrix[,2]+Hi_SD[2]
#convert the object back to a dataframe
Hi_SDValues<-as.data.frame(Hi_SDValues)
##Repeat for one SD less
Hi_SDValues_Less<-NULL
Hi_SDValues_Less$X1<-Hi_Matrix[,1]-Hi_SD[1]
Hi_SDValues_Less$X2<-Hi_Matrix[,2]-Hi_SD[2]
Hi_SDValues_Less<-as.data.frame(Hi_SDValues_Less)
This is a job for sweep (type ?sweep in R for the documentation)
Hi <- data.frame(replicate(9,sample(0:20,20,rep=TRUE)))
Hi_SD <- apply(Hi,2,sd)
Hi_SD_subtracted <- sweep(Hi, 2, Hi_SD)
You don't need to convert the dataframe to a matrix in order to add the SD
Hi<-data.frame(replicate(9,sample(0:20,20,rep=TRUE)))
Hi_SD<-apply(Hi,2,sd) # Hi_SD is a named numeric vector
Hi_SDValues<-Hi # Creating a new dataframe that we will add the SDs to
# Loop through all columns (there are many ways to do this)
for (i in 1:9){
Hi_SDValues[,i]<-Hi_SDValues[,i]+Hi_SD[i]
}
# Do pretty much the same thing for the next dataframe
Hi_SDValues_Less <- Hi
for (i in 1:9){
Hi_SDValues[,i]<-Hi_SDValues[,i]-Hi_SD[i]
}
I have a list containing 4 matrices, each with 21 random numbers in 3 columns and 7 rows.
I want to create new list using lapply function in which each matrix is sorted by the first column.
I tried:
#example data
set.seed(1)
list.a <- replicate(4, list(matrix(sample(1:99, 21), nrow=7)))
ordered <- order(list.a[,1])
lapply(list.a, function(x){[ordered,]})
but at the first step the R gives me error "incorrect number of dimensions". Don't know what to do. It works with one matrix, though.
Please help me. Thanks!
You were almost there - but you would need to iterate through the list to reorder each matrix.
Its easier to do this is one lapply statement
lapply(list.a, function(x) x[order(x[,1]),])
Note that x in the function call represents the matrices in the list.
I have the following problem within R:
I'm working with a huge matrix. Some of the columns contain the value 'zero', which leads to problems during my further work.
Hence, I want to identify the columns, which contain at least one value of 'zero'.
Any ideas how to do it?
If you have a big matrix then this would be probably faster than an apply solution:
mat[,colSums(mat==0)<0.5]
lets say your matrix is called x,
x = matrix(runif(300), nrow=10)
to get the indices of the columns that have at least 1 zero:
ix = apply(x, MARGIN=2, function(col){any(col==0)})