Reputation: 75
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
Reputation: 1843
I am late to this one, but here is another solution that will work with data.frame
s 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
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