问题
The following link
if else statement gone bad
suggests not to use the formulation
> any( c(5,6,7) )==0
[1] FALSE
I have been using any() to get rid of empty data frames in for() loops like this:
id <- c(1,2,3,4,5,6)
len <- c(11.25,11.75,12,12,12.5,13.25)
df <- data.frame(id,len)
bin.brks <- c(10,11,12,13,14)
options(warn = -1) # to turn warnings off
for (m in 1: (length(bin.brks)-1)){
#subset weights into each bin; empty when m=1
temp <- df[(df$len > bin.brks[m] & df$len <= bin.brks[m+1]),]
# deal with empty temp data frame; if the dframe is empty, this is FALSE:
if (any(temp$len)==FALSE) next
}
options(warn = 0) # restore default warnings
Of course, if I don't turn the warnings off, I get this:
Warning message:
In any(temp$var1) : coercing argument of type 'double' to logical
Is there a reason I shouldn't be getting around empty data frames this way? What would be a better way?
I actually was online trying to find a way to get around the error when I found the link that suggested I shouldn't be using any() this way at all.
回答1:
Consider creating a list of dataframes with lapply
and use Filter()
to filter out empty dataframe elements:
dfList <- lapply(seq_along(bin.brks), function(m)
df[(df$len > bin.brks[m] & df$len <= bin.brks[m+1]),])
print(dfList)
# [[1]]
# [1] id len
# <0 rows> (or 0-length row.names)
# [[2]]
# id len
# 1 1 11.25
# 2 2 11.75
# 3 3 12.00
# 4 4 12.00
# [[3]]
# id len
# 5 5 12.5
# [[4]]
# id len
# 6 6 13.25
# [[5]]
# [1] id len
# <0 rows> (or 0-length row.names)
dfList <- Filter(function(i) nrow(i) > 0, dfList)
print(dfList)
# [[1]]
# id len
# 1 1 11.25
# 2 2 11.75
# 3 3 12.00
# 4 4 12.00
# [[2]]
# id len
# 5 5 12.5
# [[3]]
# id len
# 6 6 13.25
回答2:
And here's an easy work-around from Skipping empty data frame in for loop in R:
Instead of my original
if (any(temp$len)==FALSE) next
This works:
if (nrow(temp)==0) next
来源:https://stackoverflow.com/questions/45493545/can-i-use-any-and-next-to-get-rid-of-empty-data-frames-in-r