我正在处理KDD 2010数据https://pslcdatashop.web.cmu.edu/KDDCup/downloads.jsp 在R中,如何删除具有较低实例总数的因子的行。
我尝试过以下方法: 为学生姓名因素
创建一个表studenttable <- table(data$Anon.Student.Id)
返回一个表
l5eh0S53tB Qwq8d0du28 tyU2s0MBzm dvG32rxRzQ i8f2gg51r5 XL0eQIoG72
9890 7989 7665 7242 6928 6651
然后我可以得到一个表格,告诉我给定因子水平是否有超过1000个数据点
biginstances <- studenttable>1000
然后我尝试在此查询中创建数据的子集
bigdata <- subset(data, (biginstances[Anon.Student.Id]))
但是我得到了奇怪的子集,它仍然具有原始数量的因子水平作为完整集。 我只是想删除那些在数据集中没有很好地表示的因子的行。
答案 0 :(得分:5)
可能有更有效的方法来做到这一点,但这应该可以得到你想要的。我没有使用你使用的名字,但你应该能够很好地遵循逻辑(希望!)
# Create some fake data
dat <- data.frame(id = rep(letters[1:5], 1:5), y = rnorm(15))
# tabulate the id variable
tab <- table(dat$id)
# Get the names of the ids that we care about.
# In this case the ids that occur >= 3 times
idx <- names(tab)[tab >=3]
# Only look at the data that we care about
dat[dat$id %in% idx,]
答案 1 :(得分:4)
@Dason为您提供了一些优秀的代码作为起点。我将尝试解释为什么(我认为)你尝试过的东西不起作用。
biginstances <- studenttable>1000
这将创建一个逻辑向量,其长度等于唯一学生ID的数量。 studenttable
包含data$Anon.Student.Id
的每个唯一值的计数。当您尝试在subset
中使用该逻辑向量时:
bigdata <- subset(data, (biginstances[Anon.Student.Id]))
它的长度几乎肯定远小于data
中的行数。由于subset
中的子集标准旨在识别data
行,因此R的回收规则接管并且您会看到“奇怪”的子集。
我还要补充一点,使用子集去除稀有因子级别不会更改因子的级别属性。换句话说,您将获得一个没有该级别的实例的因子,但所有原始因子级别将保留在levels属性中。例如:
> fac <- factor(rep(letters[1:3],each = 3))
> fac
[1] a a a b b b c c c
Levels: a b c
> fac[-(1:3)]
[1] b b b c c c
Levels: a b c
> droplevels(fac[-(1:3)])
[1] b b b c c c
Levels: b c
因此,如果您想确保这些级别真的“消失”,您将需要使用droplevels
。另请参阅options(stringsAsFactors = FALSE)
。
答案 2 :(得分:0)
另一种方法是在数据集和感兴趣的表之间进行连接。 我将plyr用于我的目的,但可以使用基本函数(如merge和as.data.frame.table)来完成
require(plyr)
set.seed(123)
Data <- data.frame(var1 = sample(LETTERS[1:5], size = 100, replace = TRUE),
var2 = 1:100)
R> table(Data$var1)
A B C D E
19 20 21 22 18
## rows with category less than 20
mytable <- count(Data, vars = "var1")
## mytable <- as.data.frame(table(Data$var1))
R> str(mytable)
'data.frame': 5 obs. of 2 variables:
$ var1: Factor w/ 5 levels "A","B","C","D",..: 1 2 3 4 5
$ freq: int 19 20 21 22 18
Data <- join(Data, mytable)
## Data <- merge(Data, mytable)
R> str(Data)
'data.frame': 100 obs. of 3 variables:
$ var1: Factor w/ 5 levels "A","B","C","D",..: 3 2 3 5 3 5 5 4 3 1 ...
$ var2: int 1 2 3 4 5 6 7 8 9 10 ...
$ freq: int 21 20 21 18 21 18 18 22 21 19 ...
mysubset <- droplevels(subset(Data, freq > 20))
R> table(mysubset$var1)
C D
21 22
希望这有帮助..
答案 3 :(得分:0)
这就是我设法做到这一点的方式。 我对因子和相关计数表进行了排序。
studenttable <- sort(studenttable, decreasing=TRUE)
现在我们可以合理地使用列范围了。所以我得到了数据中代表超过1000次的因子数量。
sum(studenttable>1000)
230
sum(studenttable<1000)
344
344+230=574
现在我们知道前230个因子水平是我们关心的。所以,我们可以做到
idx <- names(studenttable[1:230])
bigdata <- data[data$Anon.Student.Id %in% idx,]
我们可以通过
验证它是否有效bigstudenttable <- table(bigdata$Anon.Student.Id)
获取打印输出并查看少于1000个实例的所有因子级别现在为0。