2015-06-21 148 views
1

我有一个字符串数据框,其中大部分都是重复的。我想确定这个数据框中至少出现x次的值。确定在R数据帧中出现特定次数的值

df <- data.frame(x = c("str", "str", "str", "ing", "ing",".")) 
    occurs <- 3 

数据框包含数百个唯一字符串和数以万计的元素。在这个例子中,我如何识别哪些字符串正在发生至少三次?具体来说,我想输出符合此标准的字符串的名称,而不是数据框中的索引。

回答

7

也许table是你所需要的 - 这里是基于代码的修改示例:

> df <- data.frame(x = c("str", "str", "str", "ing", "ing",".")) 
> df 
    x 
1 str 
2 str 
3 str 
4 ing 
5 ing 
6 . 
> table(df$x) 

    . ing str 
    1 2 3 
> table(df$x) > 2 

    . ing str 
FALSE FALSE TRUE 
> names(which(table(df$x) > 2)) 
[1] "str" 
7

您还可以使用count

library(dplyr) 
df %>% count(x) 

这将调用n()计数观测次数对于每个x

# Source: local data frame [3 x 2] 
# 
#  x n 
# 1 . 1 
# 2 ing 2 
# 3 str 3 

如果你只想要那些至少发生3次,使用filter()

df %>% count(x) %>% filter(n >= 3) 

其中给出:

# Source: local data frame [1 x 2] 
# 
#  x n 
# 1 str 3 

最后,如果你只是想提取符合您的过滤条件的因素:

df %>% count(x) %>% filter(n >= 3) %>% .$x 

# [1] str 
# Levels: . ing str 

按在注释中建议由@大卫S,你也可以使用data.table

library(data.table) 
setDT(df)[, if(.N >= 3) x, by = x]$V1 

或者

setDT(df)[, .N, by = x][, x[N >= 3]] 

# [1] str 
# Levels: . ing str 

按照由@Frank建议,你也可以使用table的 “主力” tabulate

levels(df[[1]])[tabulate(df[[1]])>=3] 

# [1] "str" 

Benchmark

df <- data.frame(x = sample(LETTERS[1:26], 10e6, replace = TRUE)) 
df2 <- copy(df) 

library(microbenchmark) 
mbm <- microbenchmark(
    base = names(which(table(df$x) >= 385000)), 
    base2 = levels(df[[1]])[tabulate(df[[1]])>385000L], 
    dplyr = count(df, x) %>% filter(n >= 385000) %>% .$x, 
    DT1 = setDT(df2)[, if(.N >= 385000) x, by = x]$V1, 
    DT2 = setDT(df2)[, .N, by = x][, x[N >= 385000]], 
    times = 50 
) 

enter image description here

> mbm 
#Unit: milliseconds 
# expr  min  lq  mean median  uq  max neval cld 
# base 495.44936 523.29186 545.08199 543.56660 551.90360 652.13492 50 d 
# base2 20.08123 20.09819 20.11988 20.10633 20.14137 20.20876 50 a 
# dplyr 226.75800 227.27992 231.19709 228.36296 232.71308 259.20770 50 c 
# DT1 41.03576 41.28474 50.92456 48.40740 48.66626 168.53733 50 b 
# DT2 41.45874 41.85510 50.76797 48.93944 49.49339 74.58234 50 b 
+1

我不知道'库(data.table); setDT(df)[,如果(.N> =发生)x,by = x] $ V1'表示。或者'setDT(df)[,.N,by = x] [,x [N> = happen]]'(不知道哪个更好) –

+0

应该真快。让我把它添加到基准。 –

+0

添加时,请勿在同一数据集上运行。创建'df2 < - copy(df)',然后在'df2'上运行'data.table'基准测试。否则,'setDT'会在所有其他函数的第一次迭代中将'df'转换为'data.table'。 –