Loop with matrix accumulating values in column - r

I'm trying to make a loop to simplify:
dens1ha <- (densidade[1:45,5])
dens10ha <- (densidade[46:90,5])
dens100ha <- (densidade[91:135,5])
densfc <- (densidade[136:180,5])
denscap <- (densidade[181:225,5])
I need it stored in a single vector (x) and matrix (mm) as follows:
values of the matrix density line 1 to line 45, column 5, are stored in column 1 of vector x and the matrix mm. The line density matrix values 46 to line 90, column 5, are stored in column 2 of vector x and the matrix mm
and so on.
I tried:
x=c()
ii[1]=1
for(i in seq(1, 255, by = 44)) {
x[i]=densidade[i:(i+44),5]
ii=ii+1
mm = matrix(x,nrow=i,ncol=ii)
}

From your description of mm, I think this should do the trick:
mm <- matrix(densidade[,5], ncol=5)
You could also add names to the columns if this were desirable:
colnames(mm) <- c("dens1ha", "dens10ha", "dens100ha", "densfc", "denscap")
The goal of storing the vector x is less clear. I suspect that all of your goals may be achieved through extracting from the matrix mm rather than building a separate matrix:
# get dens1ha values as a vector
mm[,"dens1ha"]
mm[,1]
If you really would like to store these values in a separate, non-matrix structure, the most natural object to use in R is a list:
x <- list()
for(i in 1:5) {
x[[i]] <- densidade[(((i-1)*45)+1):(i*45),5]
}
# name the elements of the list
names(x) <- c("dens1ha", "dens10ha", "dens100ha", "densfc", "denscap")
You can extract vectors from this list using either
x[["dens1ha"]]
or
x[[1]]

Related

Dataframe output from a for-loop

I am trying to populate the output of a for loop into a data frame. The loop is repeating across the columns of a dataset called "data". The output is to be put into a new dataset called "data2". I specified an empty data frame with 4 columns (i.e. ncol=4). However, the output generates only the first two columns. I also get a warning message: "In matrix(value, n, p) : data length [2403] is not a sub-multiple or multiple of the number of columns [2]"
Why does the dataframe called "data2" have 2 columns, when I have specified 4 columns? This is my code:
a <- 0
b <- 0
GM <- 0
GSD <- 0
data2 <- data.frame(ncol=4, nrow=33)
for (i in 1:ncol(data))
{
if (i==34) {break}
a[i] <- colnames(data[i])
b <- data$cycle
GM[i] <- geoMean(data[,i], na.rm=TRUE)
GSD[i] <- geoSD(data[,i], na.rm=TRUE)
data2[i,] <- c(a[i], b, GM[i], GSD[i])
}
data2
If you look at the ?data.frame() help page, you'll see that it does not take arguments nrow and ncol--those are arguments for the matrix() function.
This is how you initialize data2, and you can see it starts with 2 columns, one column is named ncol, the second column is named nrow.
data2 <- data.frame(ncol=4, nrow=33)
data2
# ncol nrow
# 1 4 33
Instead you could try data2 <- as.data.frame(matrix(NA, ncol = 4, nrow = 33)), though if you share a small sample of data and your expected result there may be more efficient ways than explicit loops to get this job done.
Generally, if you do loop, you want to do as much outside of the loop as possible. This is just guesswork without having sample data, these changes seem like a start at improving your code.
a <- colnames(data)
b <- data$cycle ## this never changes, no need to redefine every iteration
GM <- numeric(ncol(data)) ## better to initialize vectors to the correct length
GSD <- numeric(ncol(data))
data2 <- as.data.frame(matrix(NA, ncol = 4, nrow = 33))
for (i in 1:ncol(data))
{
if (i==34) {break}
GM[i] <- geoMean(data[,i], na.rm=TRUE)
GSD[i] <- geoSD(data[,i], na.rm=TRUE)
## it's weird to assign a row of data.frame at once...
## maybe you should keep it as a matrix?
data2[i,] <- c(a[i], b, GM[i], GSD[i])
}
data2

R - Given a List of Vectors replace values in Vectors for each Vector with LOOP

Here is the set up. I have vec1 containing 5 numbers. I also have h5-h9 as a vector of 800 elements. The knot_list is a list of h5-h9 vectors containing 800 0's per h vector. Given x, I want to replace each h5,h6,h7,h8,h9's 800 elements with the formula x-(vec[i]) where i is 1:5 in this case.
vec1 <- c(1, 2, 3,4,5)
vec1 <- list(vec1) # needed for my real code
h5=rep(0,800);h6=h5;h7=h5;h8=h5;h9=h5
list_knot<- list(h5,h6,h7,h8,h9)
list_length <- length(list_knot) # 5
x=seq(from=1,to=800,length.out=800)
Is there a way to make the formula described above replace each vector value in each element of the list? I tried doing for loops, but syntax is wrong.
for (i in 1:list_length){
print(i)
for (j in 1:length(seq(0,800))){
list_knot[[i]][[j]] = x-vec1[[1]][[i]]^3
}
}
The list_knot is set up where it is a list containing 5 vectors. Each vector has 800 0's that need to be replaced by the formula. How can I do this?
It seems to me that this is what you are looking for
vec1 <- list(c(1, 2, 3, 4, 5)) # as per your requirement
list_knot <- lapply(vec1[[1]], function(v, x) x - v^3, x = 1:800)
, i.e., subtract each element of vec1 from the same x (1:800) and return a list of vectors. As you would like to replace every single element for each h in list_knot, you might just drop that list completely and construct a new one.

How to locate specific elements in one matrix and compare those with a second matrix?

Let's have a binary Matrix/ Data Frame:
library("Matrix")
df_binary <- data.frame(as.matrix(rsparsematrix(1000, 20,nnz = 800, rand.x = runif)))
df_binary[df_binary > 0] = 1
Now, I would like to create an index-object of all elements of equal value 1. How I can do this in R?
I need something like an index of those entries to compare the entries of the binary matrix with entries of a second matrix. Both matrices are of the same size - if this information could be important.
If you want a list out you could do something along the lines of
list_ones <- function(df) {
out <- list()
for (col in names(df)) {
out[[col]] <- which(df[[col]] == 1)
}
return(out)
}
list_ones(df_binary)

R programming - from a matrix containing points to neighbours list

I know there is a R method that enables programmers to convert neighbours list to a matrix.
I am trying to do the opposite process; is there anyway that I can convert a matrix that contains x and y coordinates of points to a neighbours list?
thank you
PS: I tried the following:
require(spdep)
mat2listw(myMatrix)$neighbours
but this is causing a problem since myMatrix has to be a square matrix...in my case my matrix is 11*2, which is not square.
You can try the following.
# need indices. Use Names or numeric index
rr <- if(is.null(rownames(myMatrix))) seq(nrow(myMatrix)) else rownames(myMatrix)
cc <- if(is.null(colnames(myMatrix))) seq(ncol(myMatrix)) else colnames(myMatrix)
inds <- as.matrix( expand.grid(X=rr, Y=cc) )
## as a data.frame
data.frame(inds, Dist=myMatrix[inds])
## as a list
ret <- apply(inds, 1, function(i) list(c(i, Dist=myMatrix[rbind(i)])))
# possibly unlist if needed
unlist(ret, recursive=FALSE)
Sample Data
set.seed(1)
myMatrix <- matrix(sample(8, 22, TRUE), ncol=2, dimnames=list(LETTERS[1:11], letters[1:2]))
myMatrix

Store/make sparse vector in R

I am generating a sparse vector length >50,000. I am producing it in a for loop. I wonder if there is an efficient way of storing the zeros?
Basically the code looks like
score = c()
for (i in 1:length(someList)) {
score[i] = getScore(input[i], other_inputs)
if (score[i] == numeric(0))
score[i] = 0 ###I would want to do something about the zeros
}
This code will not work. You should preallocate score vector size before looping. Preallocating also will create a vector with zeros. So, no need to assign zeros values, you can only assign numeric results from getScore function.
N <- length(someList) ## create a vector with zeros
score = vector('numeric',N)
for (i in 1:N) {
ss <- getScore(input[i], other_inputs)
if (length(ss)!=0)
score[i] <- ss
}

Resources