saving lists as elements of matrix - r

I am trying to add lists as an element of matrix. I am using the following code
wiip <- matrix(list(), 5, 5)
for (i in colnames(wave1)) {
for (j in colnames(wave1)) {
wiip[[i,j]] <- gclo(wave1[[i]], wave1[[j]])
}
}
the wiip[[i,j]] says subscripts out of bounds.
the output from the function gclo is a list and I want to save all the outputs. that is the double loop creates i*j(i runs over 1 to 5 and so does j, hence total 25 lists objects are created) number of lists. how to save each list together in one object.

Try to save the result in a list and use [, i] and [,j] to subset each column of the matrix.
wiip <- vector('list', ncol(wave1)*ncol(wave1))
ind <- 0
for (i in colnames(wave1)) {
for (j in colnames(wave1)) {
ind <- ind + 1
wiip[[ind]] <- gclo(wave1[, i], wave1[, j])
}
}

Related

Receiving error: argument of length 0 when reading in separate tables from multiple csv files in for loop

Error in 1:nrow(csvs) : argument of length 0 when reading in separate tables from multiple csv files
I am trying to perform the following for loop on separate tables read in from multiple csv files in the working directory. But I keep getting the error 'Error in 1:nrow(csvs) : argument of length 0'. This is what I have tried below...
# Read all csvs from files path.
csv_files <- list.files(pattern="*.csv")
csvs <- lapply(csv_files, read.table)
count <- 0
for(x in 1:nrow(csvs) - 1) {
for(y in 1:ncol(csvs)) {
if((isTRUE(csvs[x,y] == 1)) && (isTRUE(csvs[x+1,y+1] == 0))) {
count <- count + 1
}
}
}
count
This outputs nothing and shows the error: argument of length 0. Any suggestions?
I have also included a reproducible example using only one reproducible matrix below:
set.seed(99)
mat <- matrix(sample(c(0,1), 2500, prob=c(0.8,0.2), replace=TRUE), nrow=50)
count <- 0
for(x in 1:nrow(mat) - 1) {
for(y in 1:ncol(mat)) {
if((isTRUE(mat[x,y] == 1)) {
count <- count + 1
}
}
}
count
[1] 91
I can't figure out why this works for one matrix and not multiple. Can anyone help please?
You're calling nrow on a list, which won't work. Since your loop works on one matrix, and you're trying to use it on a list you could turn your loop into a function and then apply that function to your list:
yourfunction <- function (mat) {
for(x in 1:nrow(mat) - 1) {
for(y in 1:ncol(mat)) {
if(isTRUE(mat[x, y] == 1)) && (isTRUE(mat[x + 1, y] == 1))) {
counter <- counter + 1
}
}
}
counter
}
lapply(csvs, yourfunction)

Limit the values used in a function to their sum

I created a function with that I want to calculate (several) vectors of data.
Actually the vctors should be for a range (1:100) for one variable while the others stay constant at differnt values in turn.
The function is:EI <- function(x,y,z) {(x+y)/(2*(2*x+y)+z)}
my Problem is, the sum of x+y+z has to be limited to 100. And i don't know how to tell it the function.
For example, if x = 20, y can only take values from 0:80 , i.e. (100-20), and z can takey values from 0 : 100-(x+y).
I used the following code where z is not regarded all. I thought, I would get at least one large vector, but all I get is a single number:
for(x in 1:100) {
for(y in 0:(100-x)) {
for(z in 0:(100-(x+y))) {
v1 <- c(EI(x,y,z))
}
}
}
I need to tell the function EI() that the sum of x+y+z has alwys to be 100.
Has anybody an idea how to solve this problem?
If you want to create a vector you need to do that:
v1 <- c()
for(x in 1:100) {
for(y in 0:(100-x)) {
for(z in 0:(100-(x+y))) {
v1 <- c(v1, EI(x,y,z))
}
}
}
Unfortunately this will be slow (because at each step you are reallocating a new vector), a better alternative is to begin by allocate your vector with the appropriate size:
v1 <- numeric(171700)
k <- 0
for(x in 1:100) {
for(y in 0:(100-x)) {
for(z in 0:(100-(x+y))) {
k <- k + 1
v1[k] <- EI(x,y,z)
}
}
}
You can also write the same thing with sapply function and this is slightly faster:
v1 <- unlist(sapply(1:100,
function(x) {
unlist(sapply(0:(100-x),
function(y) {
sapply(0:(100-(x+y)),
function(z) {EI(x,y,z)}) }))}))

incorrect number of subscripts on matrix, for getting a plot from a matrix in R

I have a set of data, with it's own metadata. I get some of the columns to list all the data from the given set of data.
Then I use this loops to store it in a matrix (I tried a data.frame and a list, but didn't work either). The entries are strings.
#############
ii_c <- metadades$item_id[metadades$tipus_item == "comentari"]
g_c <- metadades$grup[metadades$tipus_item == "comentari"]
i_c <- metadades$item[metadades$tipus_item == "comentari"]
in_c <- data_ent[, ii_c]
c_l <- list()
for(i in 1:ncol(in_c)){
c_l[[i]] <- in_c[,i][!is.na(in_c[,i])]
}
j <- 0
l <- 0
c_cl <- matrix(ncol=3)
for(i in 1:ncol(in_c)){
if(mode(c_l[[i]])=="numeric"){
j=j+1
} else {
for(k in 1:length(c_l[i])){
c_cl[i-j+l,] = c(g_c[i],i_c[i],c_l[i][k])
l=l+1
}
}
}
df_cl <- as.data.frame(c_cl)
#############
This way afterwards I would be able to plot it. Nevertheless I've tried to list (instead of making a matrix) all the dataframes and later on I could be able to cbind them (but it gave me errors aswell).
The next step would be to do a tableGrob and a grid.draw, to print it in a report.
Got the solution from my workmate,,
df_comentaris <- data.frame(grup=NA, item=NA, comentari =NA)
for (i in metadades$item_id[metadades$tipus_item=='comentari']) {
comentaris <- dades[!is.na(dades[i]),i]
grup <- metadades$grup[metadades$item_id == i]
item <- metadades$item[metadades$item_id == i]
df_aux <- data.frame(grup=rep(grup,length(comentaris)), item=rep(item,length(comentaris)), comentari=comentaris)
df_comentaris <- rbind(df_comentaris, df_aux)
}
df_comentaris <- df_comentaris[2:nrow(df_comentaris),]

For loop function with two subscripts

I am new to writing loop functions and I am trying to solve this. I would like the y matrix to be populated with the values obtained from the for loop. Unfortunately y remains blank and full of 0's after the loop is executed.
mv <- c(0,1,2) # location vector
s <- 1 # scale
increment <- seq(-6,6,0.01) # Create a sequence of x values
y=matrix(0,length(increment),length(mv))
for (i in length(increment)) {
for (j in length(mv)) {
y[i,j] <- 1/(1+ exp(-(increment[i]-mv[j])/s))
}
}
Change your loop to start at 1, for now it is only using 1 value (length(increment)):
for (i in 1:length(increment)) {
for (j in 1:length(mv)) {
y[i,j] <- 1/(1+ exp(-(increment[i]-mv[j])/s))
}
}

Using If trying to get a vector a certain length

I'm trying to use if function to create a vector X that follows the pattern of the if statement, that is length 5. However, when I print X, I get 5 vectors with length 1. How do I fix this
for (i in 1:5) {
if (i <2){
a<-i
}
else {
a<-(i-1)
}
X<-a
print(X)
}
R overwrites the contents of your variables a and X with each loop. To avoid this, you can make X a list, and put your value in a different position with each loop.
X <- list()
a <- list()
for(i in 1:5) {
if(i<2){
a <- i
} else {
a <- i-1
}
X[i] <- a
}
Since your final plan is to create a vector, you may initialize a vector ("X") first, and then add a value ("a") in each 'for' loop.
X = vector("numeric",0)
for (i in 1:5){
if (i<2){
a <- i
}
else{
a <- (i-1)
}
X = c(X, a)
print(X)
}
X
# [1] 1 1 2 3 4

Resources