HeinKK
HeinKK

Reputation: 75

How can I delete single values in a row by condition in R?

Assume I have following matrix:

      2020-01-01 2021-01-01 2022-01-01 2022-06-06 2022-09-01 2025-01-0
[1,]       -100          0         10          0         10        120
[2,]       -200          0         30         20          0        130
[3,]       -250         20          0          0          0        280
...

Now I would like to store rows by certain conditions. For example I would like to store the first row without zeros and the 2nd row without values below zero or zero:

c(-100,10,10,120)    #Row 1 
 -100   10   10  120
c(30,20,130)         #Row 2
 30  20 130

How can I do that? Thanks for help!

Upvotes: 2

Views: 44

Answers (2)

Dunois
Dunois

Reputation: 1843

I am late to this one, but here is another solution that will work with data.frames and matrices, and will accept any generic selection condition to filter out values with. The selection itself is done by evaluating eval(parse(value, selection_condition)), and then filtering out all those that evaluate to TRUE. Then to cycle through the rows (of say, a data.frame), this function (selcol()) can be called from within a for loop, and its results stored in a list as demonstrated below:

#----

#Function to select columns based on arbitrary condition(s)
selcols <- function(myinp, mycond){

  #In theory, the user can pass whatever
  #equivalency conditions they want
  #This is just some (un)necessary checking
  #that has been commented out
  #if( grepl("^[\\-]{0,1}[0-9]+", mycond, perl = TRUE) ){
  #  mycond <- paste0("== ", mycond)
  #} else if( grepl("^>[=]*[0-9]+|^<[=]*[0-9]+", mycond, perl = TRUE) ){
  #  mycond <- mycond
  #} else{
  #  stop("Unable to parse selection condition! Check the input!")
  #}

  #Parse the equivalency conditions
  #and assign NAs accordingly
  myout <- unlist(
    lapply(as.vector(myinp), 
           function(x){
             ifelse(eval(parse(text = paste0(x, mycond))), NA, x)}))

  #Return vector of values excluding the NAs
  return(myout[!is.na(myout)])

}

#----

#----

#Your data

df <- "      2020-01-01 2021-01-01 2022-01-01 2022-06-06 2022-09-01 2025-01-0
[1,]       -100          0         10          0         10        120
[2,]       -200          0         30         20          0        130
[3,]       -250         20          0          0          0        280"

df <- as.matrix(read.table(text = df))

#----

#Example runs

#Filter out all zeroes
myl <- list()
for(i in 1:nrow(df)){
 myl[[i]] <- selcols(df[i, ], "==0")
}

myl[[1]]
# [1] -100   10   10  120

#Filter out all values less than 0
myl <- list()
for(i in 1:nrow(df)){
  myl[[i]] <- selcols(df[i, ], "<0")
}

myl[[1]]
# [1]   0  10   0  10 120

#----

Upvotes: 1

StupidWolf
StupidWolf

Reputation: 46898

Let's say your matrix is:

mat = cbind(c(-100,-200,-250),c(0,0,20),
c(10,30,0),c(0,20,0),c(10,0,0),c(120,130,280))

Then you get a list:

store_vals = apply(mat,1,function(i)i[i!=0])

Each element corresponds to each row, if you want to store row1 as a vector:

row1 = store_vals[[1]]
row1
[1] -100   10   10  120

Upvotes: 2

Related Questions