0

I'm working on a couple sparse matrices and I try to log-normalize numerical values for those > 0 while retaining those 0 values to just 0. I though it would be more convenient if I just write a for loop to loop over a list of matrices instead of calling ifelse(matrix1 > 0, log(matrix1), 0) multiple times. Here's what I got, but I can't get my code to work. I've referenced this earlier post though.

df1 <- readRDS(url("https://www.dropbox.com/s/4myqq6aqxqys4y2/comtrade2000.rds?dl=1"))
df2 <- readRDS(url("https://www.dropbox.com/s/24mthn9xtpxqwuo/comtrade2001.rds?dl=1"))
df3 <- readRDS(url("https://www.dropbox.com/s/nnywm8ysquqd5nf/comtrade2002.rds?dl=1"))

lt <- list(df1, df2, df3)

for (i in lt){
lt[i] <- ifelse(lt[i] > 0, log(lt[i]), 0)
}

## got this error message
Error in ifelse(lt[i] > 0, log(lt[i]), 0) : 
  (list) object cannot be coerced to type 'double'
Chris T.
  • 1,699
  • 7
  • 23
  • 45
  • `lt[i]` doesn't make sense. If there are 3 objects in `lt` and you want to process each object with `for` then the `for` statement should be just `for (i in 1:3)...` – SteveM Jul 26 '20 at 15:46

3 Answers3

1

Try this:

#Create function
transform_function <- function(x)
{
  index <- dim(x)[2]
  for(i in 1:index)
  {
    x[,i] <- ifelse(x[,i] > 0, log(x[,i]), 0)
  }
  return(x)
}
#Apply
lt2 <- lapply(lt,transform_function)
Duck
  • 39,058
  • 13
  • 42
  • 84
1

Referencing individual items in a list requires double square brackets. I think this should work:

df1 <- readRDS(url("https://www.dropbox.com/s/4myqq6aqxqys4y2/comtrade2000.rds?dl=1"))
df2 <- readRDS(url("https://www.dropbox.com/s/24mthn9xtpxqwuo/comtrade2001.rds?dl=1"))
df3 <- readRDS(url("https://www.dropbox.com/s/nnywm8ysquqd5nf/comtrade2002.rds?dl=1"))

lt <- list(df1, df2, df3)

for (i in 1:3){
  lt[[i]] <- ifelse(lt[[i]] > 0, log(lt[[i]]), 0)
}
Flobagob
  • 76
  • 1
  • 12
1

Try:

lognorm <- function(v)
{v[v>0]<-log(v[v>0])}

lapply(lt,lognorm)
Waldi
  • 39,242
  • 6
  • 30
  • 78