I am using R v 3.0.0 (2013-04-03) and RStudio v 1.1.463 under Win-7 64-bit.
In the following source code:
# Problem 1 - Matrix powers in R
#
# R does not have a built-in command for taking matrix powers.
# Write a function matrixpower with two arguments mat and k that
# will take integer powers k of a matrix mat.
matrixMul <- function(mat1)
{
rows <- nrow(mat1)
cols <- ncol(mat1)
matOut = matrix(, nrow = rows, ncol = cols) # empty matrix
for (i in 1:rows)
{
for(j in 1:cols)
{
vec1 <- mat1[i,]
vec2 <- mat1[,j]
mult1 <- vec1 * vec2
matOut[i,j] <- mult1
}
}
return(matOut)
}
matrixpower<-function(mat1, k)
{
matOut <-mat1#empty matix
for (i in k)
{
matOut <- matrixMul(matOut)
}
return(matOut)
}
mat1 <- matrix(c(1,2,3,4,5,6,7,8,9), nrow = 3, ncol=3)
power1 <- matrixMul(mat1)
the declaration
matOut <- matrix(, nrow = rows, ncol = cols) # empty matrix
is giving the following syntax error even before compilation:
missing argument to function call
I am following these instructions.
What am I doing wrong here?
Try this:
matOut = matrix(numeric(rows*cols), nrow = rows, ncol = cols) # empty matrix
Related
I am trying to write the following function without the for loop. Note that I am trying to replicate the function diag().
selfdiag <- function(a) {
j <- c()
for (i in 1:ncol(a)) {
j[i] <- a[i, i]
}
return(j)
}
Consider that:
mat <- matrix(rnorm(4), ncol = 2)
The function selfdiag() should create the same result as diag().
Thanks for any help on this.
You can create a data frame with the row and column indices for the diagonal and use it to extract the diagonal values from the matrix.
mat <- matrix(rnorm(4), ncol = 2)
The diag() way to do it -
diag(mat)
[1] -0.5004046 -0.8785558
The other way to do it -
rows_cols <- data.frame(rows = c(1:ncol(mat)), cols = c(1:ncol(mat)))
mat2 <- mat[as.matrix(rows_cols)]
mat2
[1] -0.5004046 -0.8785558
Hope this helps!
I know I can use expand.grid for this, but I am trying to learn actual programming. My goal is to take what I have below and use a recursion to get all 2^n binary sequences of length n.
I can do this for n = 1, but I don't understand how I would use the same function in a recursive way to get the answer for higher dimensions.
Here is for n = 1:
binseq <- function(n){
binmat <- matrix(nrow = 2^n, ncol = n)
r <- 0 #row counter
for (i in 0:1) {
r <- r + 1
binmat[r,] <- i
}
return(binmat)
}
I know I have to use probably a cbind in the return statement. My intuition says the return statement should be something like cbind(binseq(n-1), binseq(n)). But, honestly, I'm completely lost at this point.
The desired output should basically recursively produce this for n = 3:
binmat <- matrix(nrow = 8, ncol = 3)
r <- 0 # current row of binmat
for (i in 0:1) {
for (j in 0:1) {
for (k in 0:1) {
r <- r + 1
binmat[r,] <- c(i, j, k)}
}
}
binmat
It should just be a matrix as binmat is being filled recursively.
I quickly wrote this function to generate all N^K permutations of length K for given N characters. Hope it will be useful.
gen_perm <- function(str=c(""), lst=5, levels = c("0", "1", "2")){
if (nchar(str) == lst){
cat(str, "\n")
return(invisible(NULL))
}
for (i in levels){
gen_perm(str = paste0(str,i), lst=lst, levels=levels)
}
}
# sample call
gen_perm(lst = 3, levels = c("x", "T", "a"))
I will return to your problem when I get more time.
UPDATE
I modified the code above to work for your problem. Note that the matrix being populated lives in the global environment. The function also uses the tmp variable to pass rows to the global environment. This was the easiest way for me to solve the problem. Perhaps, there are other ways.
levels <- c(0,1)
nc <- 3
m <- matrix(numeric(0), ncol = nc)
gen_perm <- function(row=numeric(), lst=nc, levels = levels){
if (length(row) == lst){
assign("tmp", row, .GlobalEnv)
with(.GlobalEnv, {m <- rbind(m, tmp); rownames(m) <- NULL})
return(invisible(NULL))
}
for (i in levels){
gen_perm(row=c(row,i), lst=lst, levels=levels)
}
}
gen_perm(lst=nc, levels=levels)
UPDATE 2
To get the expected output you provided, run
m <- matrix(numeric(0), ncol = 3)
gen_perm(lst = 3, levels = c(0,1))
m
levels specifies a range of values to generate (binary in our case) to generate permutations, m is an empty matrix to fill up, gen_perm generates rows and adds them to the matrix m, lst is a length of the permutation (matches the number of columns in the matrix).
I need to convert the following code to one with for loop, what is the easiest way to do it?
set.seed(123)
iter <- 1000
s1 <- 2
mat1 <- matrix(data = rcauchy(iter*s1,0,1),nrow = iter,ncol = s1)
sets1 <- apply(mat1,1,median)
hist(sets1)
s2 <- 5
mat2 <- matrix(data = rcauchy(iter*s2,0,1),nrow = iter,ncol = s2)
sets2 <- apply(mat2,1,median)
hist(sets2)
s3 <- 10
mat3 <- matrix(data = rcauchy(iter*s3,0,1),nrow = iter,ncol = s3)
sets3 <- apply(mat3,1,median)
hist(sets3)
s4 <-20
mat4 <- matrix(data = rcauchy(iter*s4,0,1),nrow = iter,ncol = s4)
sets4 <- apply(mat4,1,median)
hist(sets4)
I tried the following:
set.seed(1234)
iter <- 1000
size <- c(2,5,10,20)
for(i in 2:size){
for (j in 1:iter){
mat[] <- matrix(data = rcauchy(i*j,0,1),nrow=iter,ncol=i)
s <- apply(mat,1,median)
hist(s)
}
}
But it does not work, please help
The easies way is to wrap the creation of the matrix into a lapply function.
set.seed(123)
iter <- 1000
size <- c(2,5,10,20)
returnmatrix<-lapply(size, function(i){
mat<-matrix(data = rcauchy(i*iter,0,1),nrow=iter,ncol=i)
s <- apply(mat,1,median)
hist(s, main=paste("Histogram when S=", i))
mat
})
The lapply function will plot the histograms and will return the matrixes as list if additional processing is desired.
I am a bit stumped on how to create a large matrix. The code I have so far are as given below. What I desire is that the rows are positions and columns are 'beta_values' from individual text files.
#Number of files = 300
#Matrix 33000 x 300
file.list <- list.files(pattern = "txt$")
# for each file, run read.table and select only the 1,2,3,12th column
columns = c('ID','S','E','Name','Alias','version','cdrive','positional','Contour','total_Contour','M_values','beta_values')
#Number of rows in the matrix
nr=33000
mat <- matrix("numeric", nrow = nr, ncol = length(file.list))
for (i in 1:length(file.list)) {
fs <- fread(file.list[i], colClasses = columns, select=c(1,2,4,12))
# Creating Position values given by paste(fs$V1,'_', fs$V2,'_',fs$V4, sep="") and 'beta_values' given by fs$V12
fs_reorder <- data.frame(paste(fs$V1,'_', fs$V2,'_',fs$V4, sep=""), fs$V12)
mat[,i] <- as.matrix(fs_reorder)
}
Error:
Error in mat[, i] <- as.matrix(fs_reorder) :
number of items to replace is not a multiple of replacement length
Quick note:
> i=1
> fs <- fread(file.list[i], select=c(1,2,4,12))
> mat <- matrix(nrow = nr, ncol = length(file.list))
> fs_reorder <- data.frame(paste(fs$V1,'_', fs$V2,'_',fs$V4, sep=""), fs$V12)
> mat[,i] <- as.matrix(fs_reorder)
Error in mat[, i] <- as.matrix(fs_reorder) :
number of items to replace is not a multiple of replacement length
> mat<- as.matrix(fs_reorder)
So this works for 1 file.
Looping through the files:
file.list_main <- list.files(pattern = "txt$")
file.list = file.list_main[1:2]
n = length(position_mat)
k = length(file.list)
mat <- matrix(nrow=n, ncol=length(file.list))
for (i in 1:length(file.list)) {
fs <- fread(file.list[i], select=c(1,2,4,12))
fs_reorder <- data.frame(paste(fs$V1,'_', fs$V2,'_',fs$V4, sep=""), fs$V12)
positions = (paste(fs$V1,'_', fs$V2,'_',fs$V4, sep=""))
betas = fs$V12
for(j in 1:k){
for(i in 1:n){
mat[i,j] = (positions[i]*betas[j])
}
}
}
Error:
Error in positions[i] * betas[j] :
non-numeric argument to binary operator
For reproducible analysis, please find the example below. Any help is very much appreciated.
set.seed(20430)
n = 1000
k = 3
fileA = rnorm(n)
fileB = rnorm(n)
fileC = rnorm(n)
positions = paste("loveletters_",rnorm(n),sep="")
betas <- cbind(fileA, fileB, fileC)
for(j in 1:k){
for(i in 1:n){
x[i,j] = (positions[i]*betas[j])
}
}
Results:
Error in positions[i] * betas[j] :
non-numeric argument to binary operator
> length(positions)
[1] 1000
> ncol(betas)
[1] 3
> nrow(betas)
[1] 1000
I have a list of 40 data sets who all have the same columns. I want to bind the 7th column of each data set. I thought about doing this with a matrix using cbind. This is my code:
RetRates <- function(q) {
q <- matrix(nrow = 766, ncol = length(ListeActions),
data = rep(0, 766), byrow = TRUE)
s <- 0
for (i in 1:length(ListeActions)) {
x <- ListeActions[[i]]
q[,i] <- cbind(q[,i], x[,9]) ## I need the 9th column
}
return(q)
}
Hedi <- matrix(nrow = 766, ncol = length(ListeActions),
data = rep(0, 766), byrow = TRUE)
Hedi <- RetRates(Hedi)
I get these warnings :
Warning messages: 1: In replace(q[, i], 1:766, x[, 9]) : the number
of objects to be replaced is not a multiple of the size of the
replacement !
Let's take a smaller example: cbind the 5th columns of each of these 3 matrices
d1 <- matrix(runif(30), 5, 6)
d2 <- matrix(rnorm(30), 5, 6)
d3 <- matrix(rnorm(30), 5, 6)
First we put the 3 matrices in a list
M <- list(d1=d1, d2=d2, d3=d3)
Then we could use, as in your question, a for loop
res1 <- matrix(NA, nrow=5, ncol=length(M))
for (i in 1:length(M)) {
res1[, i] <- M[[i]][,5]
}
Or we could use some magical R functions to get the result in one slightly more obscure command
res2 <- do.call(cbind, lapply(M, "[",,5))