vankappa
vankappa

Reputation: 81

Assign NA in conditional for loop

I'm trying to create a function that assigns NA to all columns that return TRUE on the condition ((sum of column values)/total number of rows) < 0.1

I tried something like this:

matrix <- cbind(c(0,1,1,1,0,1,0,1,0,1,0,1),
            c(1,1,1,1,0,1,0,0,1,0,0,1), 
            c(1,0,0,0,0,1,0,1,1,1,1,0),
            c(0,0,0,0,0,0,0,0,0,0,0,0))

filter10 <- function(a) {
              for (i in seq(ncol(a))) {
                if ((sum(a[,i])/nrow(a)) < 0.1) 
                  a[,i] = NA
              }
}

but nothing happens to the matrix after

> filter10(matrix)
> 

Thank you

Upvotes: 1

Views: 256

Answers (1)

jay.sf
jay.sf

Reputation: 72653

You need a return in your function, otherwise it returns nothing.

filter10 <- function(a) {
  for (i in seq(ncol(a))) {
    if ((sum(a[,i])/nrow(a)) < 0.1) 
      a[,i] = NA
  }
  return(a)
}

filter10(m)
#       [,1] [,2] [,3] [,4]
#  [1,]    0    1    1   NA
#  [2,]    1    1    0   NA
#  [3,]    1    1    0   NA
#  [4,]    1    1    0   NA
#  [5,]    0    0    0   NA
#  [6,]    1    1    1   NA
#  [7,]    0    0    0   NA
#  [8,]    1    0    1   NA
#  [9,]    0    1    1   NA
# [10,]    1    0    1   NA
# [11,]    0    0    1   NA
# [12,]    1    1    0   NA

By the way, you can also have it way easier avoiding the for loop:

filter10.1 <- function(a) {a[, colSums(a) / nrow(a) < .1] <- NA;a}
filter10.1(m)
#       [,1] [,2] [,3] [,4]
#  [1,]    0    1    1   NA
#  [2,]    1    1    0   NA
#  [3,]    1    1    0   NA
#  [4,]    1    1    0   NA
#  [5,]    0    0    0   NA
#  [6,]    1    1    1   NA
#  [7,]    0    0    0   NA
#  [8,]    1    0    1   NA
#  [9,]    0    1    1   NA
# [10,]    1    0    1   NA
# [11,]    0    0    1   NA
# [12,]    1    1    0   NA

Upvotes: 1

Related Questions