问题
how do you subset based on the number of observations of the levels of a factor variable? I have a dataset with 1,000,000 rows and nearly 3000 levels, and I want to subset out the levels with less say 200 observations.
data <- read.csv("~/Dropbox/Shared/data.csv", sep=";")
summary(as.factor(data$factor)
10001 10002 10003 10004 10005 10006 10007 10009 10010 10011 10012 10013 10014 10016 10017 10018 10019 10020
414 741 2202 205 159 591 194 678 581 774 778 738 1133 997 381 157 522 6
10021 10022 10023 10024 10025 10026 10027 10028 10029 10030 10031 10032 10033 10034 10035 10036 10037 10038
398 416 1236 797 943 386 446 542 508 309 452 482 425 272 261 291 145 598
10039 10040 10041 10043 10044 10065 10069 10075 10080 10104 10105 10106 10110 10112 10115 10117 10119 10121
119 263 9 9 179 390 70 465 19 3 7 5 4 1 1 1 2 6
10123 10128 10150 10152 10154 10155 10168 10170 10173 10174 10176 10199 10210 10220 10240 10265 10270 10271
2 611 8 1 1 2 10 1 6 5 5 2 5 2 1 3 5 2
as you see from the summary, above, there are factors with only a few obs, and I want to remove the factors that have less than 100.
I tried the following, but it didn't work:
for (n in unique((data$factor))) {
m<-subset(data, factor==n)
o<-length(m[,1])
data<-ifelse( o<100, subset(data, factor!=n), data)
}
回答1:
table
, subset that, and match based on the names of that subset. Probably will want to droplevels
thereafter.
EIDT
Some sample data:
set.seed(1234)
data <- data.frame(factor = factor(sample(10000:12999, 1000000,
TRUE, prob=rexp(3000))))
Has some categories with few cases
> min(table(data$factor))
[1] 1
Remove records from case with less than 100 of those with the same value of factor
.
tbl <- table(data$factor)
data <- droplevels(data[data$factor %in% names(tbl)[tbl >= 100],,drop=FALSE])
Check:
> min(table(data$factor))
[1] 100
Note that data
and factor
are not very good names since they are also builtin functions.
回答2:
I figured it out using the following, as there is no reason to do things twice:
function (df, column, threshold) {
size <- nrow(df)
if (threshold < 1) threshold <- threshold * size
tab <- table(df[[column]])
keep <- names(tab)[tab > threshold]
drop <- names(tab)[tab <= threshold]
cat("Keep(",column,")",length(keep),"\n"); print(tab[keep])
cat("Drop(",column,")",length(drop),"\n"); print(tab[drop])
str(df)
df <- df[df[[column]] %in% keep, ]
str(df)
size1 <- nrow(df)
cat("Rows:",size,"-->",size1,"(dropped",100*(size-size1)/size,"%)\n")
df[[column]] <- factor(df[[column]], levels=keep)
df
}
来源:https://stackoverflow.com/questions/10555858/subsetting-based-on-number-of-observations-in-a-factor-variable