459

R では、mean()median()は、期待どおりの動作をする標準関数です。 mode()引数で最も多く発生する値ではなく、オブジェクトの内部ストレージ モードを示します。しかし、ベクトル (またはリスト) の統計モードを実装する標準ライブラリ関数はありますか?

4

36 に答える 36

464

数値データと文字/因子データの両方で機能するもう 1 つのソリューション:

Mode <- function(x) {
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

私のちっぽけな小さなマシンでは、約0.5秒で10M整数ベクトルのモードを生成して見つけることができます。

データ セットに複数のモードがある場合、上記のソリューションは と同じアプローチを取り、モード セットの最初に現れる値をwhich.max返します。すべてのモードを返すには、次のバリアントを使用します (コメントの @digEmAll から):

Modes <- function(x) {
  ux <- unique(x)
  tab <- tabulate(match(x, ux))
  ux[tab == max(tab)]
}
于 2011-11-18T21:33:10.687 に答える
73

modeest単変量単変量(場合によってはマルチモーダル)データのモードの推定量と、通常の確率分布のモードの値を提供するパッケージがあります。

mySamples <- c(19, 4, 5, 7, 29, 19, 29, 13, 25, 19)

library(modeest)
mlv(mySamples, method = "mfv")

Mode (most likely value): 19 
Bickel's modal skewness: -0.1 
Call: mlv.default(x = mySamples, method = "mfv")

詳細については、このページを参照してください

于 2010-03-30T19:05:46.073 に答える
68

rメーリングリストでこれを見つけました。役に立てば幸いです。それは私がとにかく考えていたことでもあります。データを table() し、並べ替えてから、最初の名前を選択します。ハックですが、動作するはずです。

names(sort(-table(x)))[1]
于 2010-03-30T18:19:29.960 に答える
42

連続一変量分布 (正規分布など) に由来すると思われる数値のベクトルの最頻値を推定する手っ取り早い汚い方法は、次の関数を定義して使用することです。

estimate_mode <- function(x) {
  d <- density(x)
  d$x[which.max(d$y)]
}

次に、モード推定を取得します。

x <- c(5.8, 5.6, 6.2, 4.1, 4.9, 2.4, 3.9, 1.8, 5.7, 3.2)
estimate_mode(x)
## 5.439788
于 2012-12-14T08:00:22.177 に答える
14

次の関数には 3 つの形式があります。

method = "mode" [デフォルト]: ユニモーダル ベクトルのモードを計算し、そうでない場合は NA を返します
method = "nmodes": ベクトル内のモード数を計算します
method = "modes": ユニモーダルまたはポリモーダルのすべてのモードをリストしますベクター

modeav <- function (x, method = "mode", na.rm = FALSE)
{
  x <- unlist(x)
  if (na.rm)
    x <- x[!is.na(x)]
  u <- unique(x)
  n <- length(u)
  #get frequencies of each of the unique values in the vector
  frequencies <- rep(0, n)
  for (i in seq_len(n)) {
    if (is.na(u[i])) {
      frequencies[i] <- sum(is.na(x))
    }
    else {
      frequencies[i] <- sum(x == u[i], na.rm = TRUE)
    }
  }
  #mode if a unimodal vector, else NA
  if (method == "mode" | is.na(method) | method == "")
  {return(ifelse(length(frequencies[frequencies==max(frequencies)])>1,NA,u[which.max(frequencies)]))}
  #number of modes
  if(method == "nmode" | method == "nmodes")
  {return(length(frequencies[frequencies==max(frequencies)]))}
  #list of all modes
  if (method == "modes" | method == "modevalues")
  {return(u[which(frequencies==max(frequencies), arr.ind = FALSE, useNames = FALSE)])}  
  #error trap the method
  warning("Warning: method not recognised.  Valid methods are 'mode' [default], 'nmodes' and 'modes'")
  return()
}
于 2013-03-25T17:21:23.240 に答える
11

ここで、別の解決策:

freq <- tapply(mySamples,mySamples,length)
#or freq <- table(mySamples)
as.numeric(names(freq)[which.max(freq)])
于 2010-03-30T20:21:29.403 に答える
7

モードを生成するために、次のコードを書きました。

MODE <- function(dataframe){
    DF <- as.data.frame(dataframe)

    MODE2 <- function(x){      
        if (is.numeric(x) == FALSE){
            df <- as.data.frame(table(x))  
            df <- df[order(df$Freq), ]         
            m <- max(df$Freq)        
            MODE1 <- as.vector(as.character(subset(df, Freq == m)[, 1]))

            if (sum(df$Freq)/length(df$Freq)==1){
                warning("No Mode: Frequency of all values is 1", call. = FALSE)
            }else{
                return(MODE1)
            }

        }else{ 
            df <- as.data.frame(table(x))  
            df <- df[order(df$Freq), ]         
            m <- max(df$Freq)        
            MODE1 <- as.vector(as.numeric(as.character(subset(df, Freq == m)[, 1])))

            if (sum(df$Freq)/length(df$Freq)==1){
                warning("No Mode: Frequency of all values is 1", call. = FALSE)
            }else{
                return(MODE1)
            }
        }
    }

    return(as.vector(lapply(DF, MODE2)))
}

試してみよう:

MODE(mtcars)
MODE(CO2)
MODE(ToothGrowth)
MODE(InsectSprays)
于 2011-11-18T04:41:03.643 に答える
6

このハックはうまくいくはずです。モードの値とカウントを表示します。

Mode <- function(x){
a = table(x) # x is a vector
return(a[which.max(a)])
}
于 2016-09-13T07:01:34.463 に答える
4

CRAN で利用できるようになったパッケージのジェネリック関数fmodeは、collapseインデックス ハッシュに基づく C++ ベースのモードを実装します。上記のどのアプローチよりも大幅に高速です。ベクトル、行列、data.frames、および dplyr グループ化された tibbles のメソッドが付属しています。構文:

libary(collapse)
fmode(x, g = NULL, w = NULL, ...)

wherexは上記のオブジェクトの 1 つにすることができg、オプションのグループ化ベクトルまたはグループ化ベクトルのリスト (グループ化されたモード計算の場合、C++ でも実行されるw) を提供し、(オプションで) 数値の重みベクトルを提供します。グループ化された tibble メソッドでは、g引数はなく、実行できますdata %>% group_by(idvar) %>% fmode

于 2020-03-19T21:45:11.423 に答える
3

Rには非常に多くのアドオンパッケージがあり、そのうちのいくつかは数値リスト/シリーズ/ベクトルの[統計]モードを提供する可能性があります.

しかし、R 自体の標準ライブラリには、そのような組み込みメソッドはないようです。これを回避する1つの方法は、次のような構造を使用することです(頻繁に使用する場合は、これを関数に変換します...):

mySamples <- c(19, 4, 5, 7, 29, 19, 29, 13, 25, 19)
tabSmpl<-tabulate(mySamples)
SmplMode<-which(tabSmpl== max(tabSmpl))
if(sum(tabSmpl == max(tabSmpl))>1) SmplMode<-NA
> SmplMode
[1] 19

より大きなサンプル リストについては、 max(tabSmpl) 値に一時変数を使用することを検討する必要があります (R がこれを自動的に最適化するかどうかはわかりません)。

参考:「中央値と最頻値は?」参照 このKickStarting R レッスン
で は、これは (少なくともこのレッスンの執筆時点では) R にモード関数がないことを確認しているようです (まあ... mode() は、変数の型をアサートするために使用されます) )。

于 2010-03-30T18:25:50.147 に答える
3

これはかなりうまくいきます

> a<-c(1,1,2,2,3,3,4,4,5)
> names(table(a))[table(a)==max(table(a))]
于 2014-02-07T04:16:37.170 に答える
3

モードを見つける関数は次のとおりです。

mode <- function(x) {
  unique_val <- unique(x)
  counts <- vector()
  for (i in 1:length(unique_val)) {
    counts[i] <- length(which(x==unique_val[i]))
  }
  position <- c(which(counts==max(counts)))
  if (mean(counts)==max(counts)) 
    mode_x <- 'Mode does not exist'
  else 
    mode_x <- unique_val[position]
  return(mode_x)
}
于 2015-09-06T09:09:18.273 に答える
2

density() 関数を使用して、平滑化された (おそらく連続的な) 分布の最大値を識別します。

function(x) density(x, 2)$x[density(x, 2)$y == max(density(x, 2)$y)]

ここで、x はデータ コレクションです。スムージングを調整する密度関数の調整パラメーターに注意してください。

于 2014-05-02T10:03:41.453 に答える
2

私はこれらすべてのオプションを調べていて、それらの相対的な機能とパフォーマンスについて疑問に思い始めたので、いくつかのテストを行いました. 他の誰かが同じことに興味がある場合に備えて、ここで結果を共有しています。

ここに掲載されているすべての関数について気にする必要はありませんが、いくつかの基準に基づいてサンプルに焦点を当てることにしました。関数は、文字ベクトル、因子ベクトル、論理ベクトル、および数値ベクトルの両方で機能する必要があり、NA やその他の問題のある値を適切に処理する必要があります。出力は「賢明」でなければなりません。

rleまた、より一般的な使用に適応することを除いて、クリスピーと同じアイデアに基づいた独自の関数も追加しました。

library(magrittr)

Aksel <- function(x, freq=FALSE) {
    z <- 2
    if (freq) z <- 1:2
    run <- x %>% as.vector %>% sort %>% rle %>% unclass %>% data.frame
    colnames(run) <- c("freq", "value")
    run[which(run$freq==max(run$freq)), z] %>% as.vector   
}

set.seed(2)

F <- sample(c("yes", "no", "maybe", NA), 10, replace=TRUE) %>% factor
Aksel(F)

# [1] maybe yes  

C <- sample(c("Steve", "Jane", "Jonas", "Petra"), 20, replace=TRUE)
Aksel(C, freq=TRUE)

# freq value
#    7 Steve

最終的に、2 セットのテスト データに対して 5 つの関数を実行することになりましたmicrobenchmark。関数名は、それぞれの作成者を示しています。

ここに画像の説明を入力

Chris の関数は、より比較しやすいようにデフォルトでmethod="modes"andに設定さna.rm=TRUEれていましたが、それ以外の関数は、ここで作成者が提示したとおりに使用されました。

速度だけの問題では、Kens バージョンが手軽に勝ちますが、実際にいくつあっても、1 つのモードのみを報告するのはこれらのバージョンの 1 つだけです。よくあることですが、速度と汎用性の間にはトレードオフがあります。ではmethod="mode"、Chris のバージョンは、モードが 1 つしかない場合は値を返し、それ以外の場合は NA を返します。いい感じだと思います。また、一意の値の数の増加によって一部の機能が影響を受け、他の機能はそれほど影響を受けないことも興味深いと思います。原因として論理/数値を排除することを除いて、その理由を理解するためにコードを詳細に調査していません。

于 2016-05-27T02:49:33.367 に答える
2

Ken Williams の単純な関数が好きですが、複数のモードが存在する場合はそれらを取得したいと考えています。それを念頭に置いて、複数または単一の場合にモードのリストを返す次の関数を使用します。

rmode <- function(x) {
  x <- sort(x)  
  u <- unique(x)
  y <- lapply(u, function(y) length(x[x==y]))
  u[which( unlist(y) == max(unlist(y)) )]
} 
于 2014-12-24T16:08:02.960 に答える
2

頻度で並べ替えられたすべての値を与える別の簡単なオプションは、次を使用することrleです。

df = as.data.frame(unclass(rle(sort(mySamples))))
df = df[order(-df$lengths),]
head(df)
于 2012-12-04T14:29:14.487 に答える
1

別の可能な解決策:

Mode <- function(x) {
    if (is.numeric(x)) {
        x_table <- table(x)
        return(as.numeric(names(x_table)[which.max(x_table)]))
    }
}

使用法:

set.seed(100)
v <- sample(x = 1:100, size = 1000000, replace = TRUE)
system.time(Mode(v))

出力:

   user  system elapsed 
   0.32    0.00    0.31 
于 2015-12-16T02:45:39.433 に答える
-1

すみません、単純すぎるかもしれませんが、これでうまくいきませんか?(私のマシンでは 1E6 値で 1.3 秒):

t0 <- Sys.time()
summary(as.factor(round(rnorm(1e6), 2)))[1]
Sys.time()-t0

「round(rnorm(1e6),2)」をベクターに置き換えるだけです。

于 2013-04-10T14:33:52.757 に答える
-2

Theta(N) 実行時間で実行できるいくつかの方法を次に示します。

from collections import defaultdict

def mode1(L):
    counts = defaultdict(int)
    for v in L:
        counts[v] += 1
    return max(counts,key=lambda x:counts[x])

def mode2(L):
    vals = set(L)
    return max(vals,key=lambda x: L.count(x))
def mode3(L):
    return max(set(L), key=lambda x: L.count(x))
于 2020-03-31T03:44:06.687 に答える