问题
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)
}
回答1:
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), ]
回答2:
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
来源:https://stackoverflow.com/questions/36930138/how-to-use-a-loop-to-delete-all-rows-with-negative-values-in-r