Tyler
Tyler

Reputation: 23

How to use a loop to delete all rows with negative values in R

I am new to loops. I have an unwieldy data frame that I want to cut down so that only observations (rows) without negative numbers remain. Here is where I'm stuck. This creates a null value every time instead of a trimmed down data frame.

    mydata=for (i in names(df)) {
      subset(df, df[[ paste(i)]]>=0) 
    }

Upvotes: 0

Views: 1073

Answers (2)

SymbolixAU
SymbolixAU

Reputation: 26258

How about a purely vectorised solution:

DF[!rowSums(DF < 0), ]
#  ID Items Sequence
#1  1     D        1
#2  1     A        2
#5  2     B        2

Data

DF=structure(list(ID = c(1, 1, 1, -1, 2), Items = c("D", "A", "A", 
"A", "B"), Sequence = c(1, 2, -2, 1, 2)), .Names = c("ID", "Items", 
"Sequence"), row.names = c(NA, -5L), class = "data.frame")

Explanation

The comparison DF < 0 gives TRUE/FALSE for every value in the data.frame

DF < 0
#         ID Items Sequence
# [1,] FALSE FALSE    FALSE
# [2,] FALSE FALSE    FALSE
# [3,] FALSE FALSE     TRUE
# [4,]  TRUE FALSE    FALSE
# [5,] FALSE FALSE    FALSE

rowSums() then gives us the sum of each row (as TRUE == 1, FALSE == 0)

rowSums(DF<0)
# [1] 0 0 1 1 0

So we can use this vector to subset our data.frame. But, because we want it where the values are all positive (i.e. rowSums == 0), we negate the filter

DF[!rowSums(DF < 0), ]

Upvotes: 6

Silence Dogood
Silence Dogood

Reputation: 3597

You don't need loops for this :)

DF=structure(list(ID = c(1, 1, 1, -1, 2), Items = c("D", "A", "A", 
"A", "B"), Sequence = c(1, 2, -2, 1, 2)), .Names = c("ID", "Items", 
"Sequence"), row.names = c(NA, -5L), class = "data.frame")

 DF
#  ID Items Sequence
#1  1     D        1
#2  1     A        2
#3  1     A       -2
#4 -1     A        1
#5  2     B        2


new_DF = DF[apply(DF<0,1,function(x) !any(x)),]

new_DF
#  ID Items Sequence
#1  1     D        1
#2  1     A        2
#5  2     B        2

Upvotes: 3

Related Questions