2016-08-20 65 views
0

名义变量我有类似这样的一个数据集:子集R中

x <- sample(c("A", "B", "C", "D"), 1000, replace=TRUE, prob=c(0.1, 0.2, 0.65, 0.05)) 
y <- sample(1:40, 1000, replace=TRUE) 
d <- data.frame(x,y) 

str(d) 
'data.frame': 1000 obs. of 2 variables: 
$ x: Factor w/4 levels "A","B","C","D": 1 3 3 2 3 3 3 3 4 3 ... 
$ y: int 28 35 14 4 34 36 30 35 26 9 ... 

table(d$x) 
A B C D 
115 204 637 44 

所以在我的真实数据集,我有数千个这些类别(A,B,C,d)。

我的真实数据集的str()

str(realdata) 
data.frame': 346340 obs. of 91 variables: 
$ author  : Factor w/ 42590 levels "-jon-","--LZR--",..: 1962 3434 1241 7666 6235 2391 1196 2779 1881 339 ... 
$ created_utc : Factor w/ 343708 levels "2015-05-01 02:00:41",..: 14815 23163 2281 3569 5922 7211 15783 5512 13485 8591 ... 
$ group : Factor w/ 5 levels "xyz","abc","bnm",..: 2 2 2 2 2 2 2 2 2 2 ... 
.... 

现在我想子集数据,所以我只有那些$作家(在d数据帧或$x)在我的新数据框中有更多的行总共超过100个条目。

我试过如下:

dnew <- subset(realdata, table(realdata$author) > 100) 

它给了我一个结果,但它似乎被纳入作者的不是所有的条目。虽然它应该是更多,我只得到完整数据集的行的1.3%。我手工检查(用Excel),它应该比这更多(约30%)。手动分析显示,1.2%的$作者占30%的参赛作品。所以看起来他只给了我一行有超过100个条目的$作者,但不是他所有的条目。

你知道一个方法来解决这个问题吗?

回答

1

I.数据帧d与四个级别

table(d$x) 

    # A B C D 
    # 92 232 630 46 

II。检查哪个级别有超过100条记录

which(table(d$x)>100) 
    # B C 
    # 2 3 

三。子集d仅具有属于具有大于100个记录的级别的记录的数据帧,即,level Blevel C

result <- d[ d$x %in% names(table(d$x))[table(d$x) > 100] , ] 
    dim(result) 
    # [1] 862 2 

    str(result) 
    # 'data.frame': 862 obs. of 2 variables: 
    # $ x: Factor w/ 4 levels "A","B","C","D": 3 2 3 3 2 2 2 3 3 3 ... 
    # $ y: int 29 32 27 40 30 38 8 16 2 23 ... 

水平AD0 records

table(result$x) 

    # A B C D 
    # 0 232 630 0 

IV仍然存在。使用0记录删除级别factor()

result$x <- factor(result$x) 

    str(result) 
    # 'data.frame': 860 obs. of 2 variables: 
    # $ x: Factor w/ 2 levels "B","C": 2 2 1 2 1 2 2 2 1 2 ... 
    # $ y: int 29 32 27 40 30 38 8 16 2 23 ... 

    table(result$x) 
    # B C 
    # 232 630 
+1

谢谢,这工作! –

+1

@akrun我不知道你已经添加了,对于我的答案,我使用了两个链接的组合,我试了一下,然后发布,这里是http://stackoverflow.com/questions/24835233/subset-based-on-频率级 http://stackoverflow.com/questions/1195826/drop-factor-levels-in-a-subsetted-data-frame 你的答案为基地R也奏效我也检查过,水平仍然坚持数据,所以我在第二个链接之后放弃了它们。 谢谢。 –

3

我们可以用data.table轻松做到这一点。转换 'data.frame' 到 'data.table'(setDT(d),由 'x' 的分组,if观测的数量是大于100,我们子集Data.table(.SD

library(data.table) 
ddt <- setDT(d)[, if(.N > 100) .SD, x] 

或者,如果我们使用dplyr,同样的方法可以使用。

library(dplyr) 
dpl <- d %>% 
     group_by(x) %>% 
     filter(n() > 100) %>% 
     droplevels() 
str(dpl) 
#Classes ‘grouped_df’, ‘tbl_df’, ‘tbl’ and 'data.frame': 866 obs. of 2 variables: 
#$ x: Factor w/ 2 levels "B","C": 1 1 2 1 1 2 2 2 2 2 ... 
# $ y: int 25 25 13 11 2 32 12 15 12 3 ... 

此外,在使用base R,在table可以b Ë有用

v1 <- table(d$x) 
d1 <- subset(d, x %in% names(v1)[v1 > 100]) 

由于列 'x' 为factor,当我们subset数据集,该水平持续,由于OP没有设置seed以消除使用droplevels

d2 <- droplevels(d1) 

,每个人的产出都不一样。

str(d2) 
#'data.frame': 866 obs. of 2 variables: 
#$ x: Factor w/ 2 levels "B","C": 1 1 2 1 1 2 2 2 2 2 ... 
#$ y: int 25 25 13 11 2 32 12 15 12 3 ... 
+0

我试过用dplyr的版本。它适用于测试数据框。唉,我将它应用到我的真实数据集时收到错误消息:错误:无效的下标类型'整数'。我检查,$作者是一个因素,因为是x。我使用了以下命令auth < - realdata%>%group_by(realdata $ author)%>%filter(n()> 100) –

+0

@ 8bytez我还提供了另外两个解决方案,一个使用'data.table',另一个使用'subset'。您接受的解决方案使用的是我首先发布的相同逻辑。这太疯狂了。 – akrun

+0

@ 8bytez你甚至没有在我的代码中使用语法'group_by(realdata $ author)'我没有被使用。 – akrun