2014-03-01 88 views
3

我在R變量中有一組字符串,當我檢查這個類時,它說這是一個因子。 例如。獲取R中因子中最頻繁的元素R

mySet<-c("abc","abc","def","abc","def","efg","abc") 

我想要得到在這個集合中出現最大次數的字符串(即在這種情況下爲「abc」)。

我明白一種方法是使用hist(),但我面臨的數據類型問題,因爲我是R新手,我無法自己破解這一個。在sqibb

回答

12

根據您的數據的大小,以及您需要做這樣一個練習的頻率,你可能要花費一些時間來編寫一個更有效的作用。底層tabletabulate,這是更快,從而可能會導致像下面這樣的函數:

MaxTable <- function(InVec, mult = FALSE) { 
    if (!is.factor(InVec)) InVec <- factor(InVec) 
    A <- tabulate(InVec) 
    if (isTRUE(mult)) { 
    levels(InVec)[A == max(A)] 
    } 
    else levels(InVec)[which.max(A)] 
} 

該功能的目的是還確定當有針對的最高值多值。比較以下內容:

mySet <- c("A", "A", "A", "B", "B", "B", "C", "C") 
## Your question indicates that you have factors, 
## but your sample code is a character vector 
mySetF <- factor(mySet) ## Just as an example 

## @BrodieG's answer 
fun1 <- function(InVec) { 
    names(which.max(table(InVec))) 
} 

## @sgibb's answer 
fun2 <- function(InVec) { 
    m <- which.max(table(as.character(InVec))) 
    as.character(InVec)[m] 
} 

fun1(mySet) 
# [1] "A" 
fun2(mySet) 
# [1] "A" 
MaxTable(mySet) 
# [1] "A" 
MaxTable(mySet, mult = TRUE) 
# [1] "A" "B" 

library(microbenchmark)  
microbenchmark(fun1(mySet), fun2(mySet), MaxTable(mySet), MaxTable(mySetF)) 
# Unit: microseconds 
#    expr  min  lq median  uq  max neval 
#  fun1(mySet) 291.457 297.1845 302.2080 313.1235 3008.108 100 
#  fun2(mySet) 296.388 302.0775 311.3170 321.5260 1367.137 100 
# MaxTable(mySet) 172.463 180.8755 184.8355 189.9700 1947.700 100 
# MaxTable(mySetF) 34.510 38.1545 44.6045 46.6695 95.341 100 

在小向量級別,此函數更有效。這在factor載體中更加明顯。如何更大的載體?

set.seed(1) 
medSet <- sample(c(LETTERS, letters), 1e5, TRUE) 
medSetF <- factor(medSet) 

fun1(medSet) 
# [1] "E" 
fun2(medSet) ### Wrong Answer!!! 
# [1] "D" 
MaxTable(medSet) 
# [1] "E" 

microbenchmark(fun1(medSet), MaxTable(medSet), MaxTable(medSetF)) 
# Unit: microseconds 
#    expr  min  lq  median  uq  max neval 
#  fun1(medSet) 14222.846 14350.957 14484.4490 14600.490 34810.174 100 
# MaxTable(medSet) 7787.761 7860.248 7917.3455 8019.068 9762.884 100 
# MaxTable(medSetF) 501.733 529.257 570.0735 587.936 1469.994 100 

我已經下降@從基準sgibb的功能(它運行在大約相同的時間fun1()),因爲它會返回錯誤的答案。

最後一個標杆....

set.seed(3) 
bigSet <- sample(c(LETTERS, letters), 1e7, TRUE) 
bigSetF <- factor(bigSet) 
microbenchmark(fun1(bigSet), MaxTable(bigSet), MaxTable(bigSetF), times = 10) 
# Unit: milliseconds 
#    expr  min   lq  median   uq  max neval 
#  fun1(bigSet) 1519.37503 1612.10290 1648.36473 1789.02965 1932.41073 10 
# MaxTable(bigSet) 782.01856 791.86408 834.35764 894.60535 1019.28747 10 
# MaxTable(bigSetF) 48.56459 48.76492 49.25444 49.93911 50.20404 10 
+1

+1,顯着的性能差異。 – BrodieG

+0

它如何處理關係? –

+0

@ Hack-R,這就是'mult = TRUE'設置的用途。這是你的意思嗎? – A5C1D2H2I1M1N2O1R2T1

4

變化:

names(which.max(table(mySet))) 
# [1] "abc" 
+1

這不是@ sgibb的答案的變化。這是他答案的正確版本。 – A5C1D2H2I1M1N2O1R2T1

+0

警告:這不會處理經常出現兩個值的情況。 – BurninLeo