You're looking for droplevels
.
Here's some sample data similar to yours:
set.seed(1)
mydf <- data.frame(A = factor(rep("M", 5), levels = c("M", "F")),
B = sample(20:50, 5, TRUE))
mydf$C <- cut(mydf$B, seq(0, 80, 10))
mydf
# A B C
# 1 M 28 (20,30]
# 2 M 31 (30,40]
# 3 M 37 (30,40]
# 4 M 48 (40,50]
# 5 M 26 (20,30]
summary(mydf)
# A B C
# M:5 Min. :26 (20,30]:2
# F:0 1st Qu.:28 (30,40]:2
# Median :31 (40,50]:1
# Mean :34 (0,10] :0
# 3rd Qu.:37 (10,20]:0
# Max. :48 (50,60]:0
# (Other):0
Now, let's use droplevels
and see what happens:
mydf2 <- droplevels(mydf)
summary(mydf2)
# A B C
# M:5 Min. :26 (20,30]:2
# 1st Qu.:28 (30,40]:2
# Median :31 (40,50]:1
# Mean :34
# 3rd Qu.:37
# Max. :48
If you really wanted to use an *apply
approach, perhaps you can use lapply
as follows:
mydf3 <- mydf ## Create a copy of your original just in case
mydf3[] <- lapply(mydf3, factor)
summary(mydf3)
# A B C
# M:5 26:1 (20,30]:2
# 28:1 (30,40]:2
# 31:1 (40,50]:1
# 37:1
# 48:1