모드를 찾기위한 내장 함수가 있습니까?


392

R에서, mean()그리고 median()당신이 기대하는 일을 표준 기능은 다음과 같습니다. mode()인수에서 가장 많이 발생하는 값이 아니라 객체의 내부 저장 모드를 알려줍니다. 그러나 벡터 (또는 목록)에 대한 통계 모드를 구현하는 표준 라이브러리 함수가 있습니까?


4
데이터가 정수, 숫자, 요소인지 여부를 명확히해야합니까? 숫자에 대한 모드 추정은 다르며 구간을 사용합니다. 겸손
smci

2
R에 모드에 내장 기능이없는 이유는 무엇입니까? R은 왜 mode함수와 같은 것으로 간주 class합니까?
Corey Levinson

답변:


400

숫자 및 문자 / 인자 데이터 모두에 사용할 수있는 또 하나의 솔루션 :

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)]
}

7
논리에 대해서도 작동합니다! 다른 답변의 일부 구현과 달리 모든 유형의 벡터에 대해 데이터 유형을 유지합니다.
DavidC

39
멀티 모달 데이터 셋 (예 :)의 경우 모든 모드를 반환하지는 않습니다 c(1,1,2,2). 마지막 줄을 다음과 같이 변경해야합니다.tab <- tabulate(match(x, ux)); ux[tab == max(tab)]
digEmAll

6
@verybadatthis이를 위해 당신은 ux[which.max(tabulate(match(x, ux)))]just로 대체 할 것 max(tabulate(match(x, ux)))입니다.
Ken Williams

4
당신은주의 Mode(1:3)제공 1하고 Mode(3:1)있습니다 3그들 모두가 고유 모드 인 경우가 가장 흔한 요소 또는 첫 번째를 반환, 그래서.
Enrique Pérez Herrero

2
Enrique가 말했듯이 : 모드가 없으면 실패하고 대신 첫 번째 값이 모드 라는 인상을줍니다 . 그것이 반환 0되거나 NA그 경우 에 훨씬 좋았을 것 입니다.
not2qubit

66

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")

자세한 내용은 이 페이지를 참조 하십시오


7
따라서 모드 값을 얻으려면 mfv(mySamples)[1]. 1실제로 가장 빈번한 값 반환으로 중요한 존재 .
atomules

이 예제에서는 작동하지 않는 것 같습니다 : library (modeest) a <-rnorm (50, 30, 2) b <-rnorm (100, 35, 2) c <-rnorm (20, 37, 2) 온도 ºC <- c (a, b, c) hist (온도 ºC) # 평균 abline (v = 평균 (temperatureºC), col = "red", lwd = 2) #median abline (v = median (temperatureºC), col = "black", lwd = 2) #mode abline (v = mlv (온도 ºC, 방법 = "mfv") [1], col = "orange", lwd = 2)
Agus camacho

1
@atomicules : [1]에서는 첫 번째 모드 만 얻습니다. 바이 모달 또는 일반 n- 모달 분포의 경우mfv(mySamples)
petzi

1
R 버전 3.6.0의 경우 '함수'mlv '를 찾을 수 없습니다'라는 함수와 mfv (mysamples)를 시도했을 때 동일한 오류가 표시됩니다. 감가 상각됩니까?
Nisha Arora 박사 1

@ DrNishaArora : '최소의'패키지를 다운로드 했습니까?
petzi

59

r 메일 링리스트에서이 정보를 찾았 으면 도움이 되길 바랍니다. 어쨌든 내가 생각했던 것이기도합니다. 데이터를 table ()하고 정렬 한 다음 이름을 선택합니다. 그것은 hackish이지만 작동해야합니다.

names(sort(-table(x)))[1]

6
그것은 또한 영리한 해결 방법입니다. 정렬 알고리즘은 max () 기반 접근 방식보다 더 많은 공간과 시간을 소비 할 수 있습니다 (=>는 더 큰 샘플 목록에서는 피해야 함). 또한 출력은 "숫자"가 아닌 "문자"모드입니다. 물론 다중 모달 분포를 테스트 할 때는 정렬 된 테이블을 새로 저장하지 않기 위해 일반적으로 정렬 된 테이블을 저장해야합니다.
mjv

2
1e6 요소의 요소로 실행 시간을 측정 했으며이 솔루션은 거의 요소 3에서 허용되는 답변보다 빠릅니다!
vonjd 2016

방금 as.numeric ()을 사용하여 숫자로 변환했습니다. 완벽하게 작동합니다. 감사합니다!
Abhishek Singh

47

위의 Ken Williams 게시물이 훌륭하다는 것을 알았고 NA 값을 설명하기 위해 몇 줄을 추가하여 쉽게 사용할 수 있도록 만들었습니다.

Mode <- function(x, na.rm = FALSE) {
  if(na.rm){
    x = x[!is.na(x)]
  }

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

나는 이것에 대한 몇 가지 속도 향상을 발견했다. 아래 답변을 참조하십시오.
Dan Houghton

33

연속 일 변량 분포 (예를 들어 정규 분포)에서 나온 것으로 생각되는 숫자 벡터의 모드를 추정하는 빠르고 더러운 방법은 다음 함수를 정의하고 사용하는 것입니다.

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

3
이것에 대한 참고 사항 :이 방법으로 연속 그룹의 "모드"를 얻을 수 있습니다. 데이터가 정규 분포에서 나오지 않아도 작동합니다. 다음은 균일 분포에서 숫자를 취하는 예입니다. set.seed(1); a<-runif(100); mode<-density(a)$x[which.max(density(a)$y)]; abline(v=mode)
Jota

error in density.default(x, from = from, to = to) : need at least 2 points to select a bandwidth automatically
Sergio

@xhie이 오류 메시지는 알아야 할 모든 것을 알려줍니다. 포인트가 하나만 있으면를 호출 할 때 대역폭을 수동으로 설정해야합니다 density. 그러나 하나의 데이터 포인트 만 있다면 해당 데이터 포인트의 값은 아마도 어쨌든 모드에 대한 최선의 추측 일 것입니다.
Rasmus Bååth

당신 말이 맞지만 한 가지 조정 만 추가했습니다 estimate_mode <- function(x) { if (length(x)>1){ d <- density(x) d$x[which.max(d$y)] }else{ x } } . 원형 패키지에 벡터 평균을 사용하는 방향 대신 평균 방향 바람을 추정하는 방법을 테스트하고 있습니다. 다각형 등급 이상의 점으로 작업하므로 방향이있는 점이 하나만있는 경우가 있습니다. 감사!
Sergio

@ xhie는 합리적인 소리 :)
Rasmus Bååth

14

다음 기능은 세 가지 형태로 제공됩니다.

method = "mode"[default] : 단봉 벡터의 모드를 계산합니다. 그렇지 않으면 NA
메서드를 반환합니다. = "nmodes": 벡터
방식 의 모드 수를 계산합니다. = "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()
}

이 기능에 대한 설명에서 "모드"와 "n 모드"를 교체했습니다. 코드를 참조하십시오. 실제로 "nmodes"는 값의 벡터를 반환하고 "modes"는 모드 수를 반환합니다. 그럼에도 불구하고 귀하의 기능은 지금까지 본 모드를 찾는 가장 좋은 영혼입니다.
Grzegorz Adam Kowalski

댓글 주셔서 감사합니다. "nmode"및 "modes"가 이제 예상대로 작동합니다.
Chris

을 사용하여 각 값이 동일하게 자주 발생하는 경우를 제외하고 함수는 거의 작동합니다 method = 'modes'. 그런 다음이 함수는 모든 고유 값을 반환하지만 실제로는 모드가 없으므로 NA대신 반환해야 합니다. 영감을 얻은 덕분에 약간 최적화 된 버전의 함수가 포함 된 다른 답변을 추가 할 것입니다!
hugovdberg 2016 년

비어 있지 않은 숫자 형 벡터가 일반적으로이 함수를 사용하여 NA를 생성해야하는 유일한 시간은 다 봉형 벡터에서 기본 방법을 사용할 때입니다. 1,2,3,4와 같은 간단한 숫자 시퀀스의 모드는 실제로 시퀀스의 모든 숫자이므로 유사한 시퀀스의 경우 "모드"가 예상대로 작동합니다. 예를 들어 modeave (c (1,2,3,4), method = "modes")는 [1] 1 2 3 4를 반환합니다. 현재 상태
Chris

이 함수의보다 효율적인 버전은 위의 @ hugovdberg 's post를 참조하십시오.
Chris

10

또 다른 해결책은 다음과 같습니다.

freq <- tapply(mySamples,mySamples,length)
#or freq <- table(mySamples)
as.numeric(names(freq)[which.max(freq)])

첫 번째 줄을 테이블로 바꿀 수 있습니다.
Jonathan Chang

'tapply'가 'table'보다 효율적이라고 생각했지만 둘 다 for 루프를 사용합니다. 테이블이있는 솔루션은 동일하다고 생각합니다. 답변을 업데이트합니다.
teucer

9

아직 투표를 할 수 없지만 Rasmus Bååth의 답변은 제가 찾던 것입니다. 그러나 0과 1 사이의 값을 예로 들어 배포를 금하도록 약간 수정합니다.

estimate_mode <- function(x,from=min(x), to=max(x)) {
  d <- density(x, from=from, to=to)
  d$x[which.max(d$y)]
}

배포를 전혀 제한하지 않으려면 =- "BIG NUMBER"에서 = "BIG NUMBER"로 설정하십시오.


error in density.default(x, from = from, to = to) : need at least 2 points to select a bandwidth automatically
Sergio

x는 벡터 여야합니다
AleRuete

8

선택적 매개 변수 na.rm및을 추가하여 Ken Williams의 답변을 약간 수정했습니다 return_multiple.

에 의존하는 답변과 달리이 names()답변은의 데이터 유형을 x반환 된 값으로 유지합니다 .

stat_mode <- function(x, return_multiple = TRUE, na.rm = FALSE) {
  if(na.rm){
    x <- na.omit(x)
  }
  ux <- unique(x)
  freq <- tabulate(match(x, ux))
  mode_loc <- if(return_multiple) which(freq==max(freq)) else which.max(freq)
  return(ux[mode_loc])
}

선택적 params와 함께 작동하고 데이터 유형을 유지함을 표시하려면 다음을 수행하십시오.

foo <- c(2L, 2L, 3L, 4L, 4L, 5L, NA, NA)
bar <- c('mouse','mouse','dog','cat','cat','bird',NA,NA)

str(stat_mode(foo)) # int [1:3] 2 4 NA
str(stat_mode(bar)) # chr [1:3] "mouse" "cat" NA
str(stat_mode(bar, na.rm=T)) # chr [1:2] "mouse" "cat"
str(stat_mode(bar, return_mult=F, na.rm=T)) # chr "mouse"

단순화를 위해 @Frank에게 감사합니다.


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)

6

@Chris의 기능을 기반으로 모드 또는 관련 메트릭을 계산하지만 Ken Williams의 방법을 사용하여 주파수를 계산합니다. 이것은 모드가 전혀없는 경우 (모든 요소가 똑같이 자주 발생하는 경우) 및 더 읽기 쉬운 method이름을 수정합니다.

Mode <- function(x, method = "one", na.rm = FALSE) {
  x <- unlist(x)
  if (na.rm) {
    x <- x[!is.na(x)]
  }

  # Get unique values
  ux <- unique(x)
  n <- length(ux)

  # Get frequencies of all unique values
  frequencies <- tabulate(match(x, ux))
  modes <- frequencies == max(frequencies)

  # Determine number of modes
  nmodes <- sum(modes)
  nmodes <- ifelse(nmodes==n, 0L, nmodes)

  if (method %in% c("one", "mode", "") | is.na(method)) {
    # Return NA if not exactly one mode, else return the mode
    if (nmodes != 1) {
      return(NA)
    } else {
      return(ux[which(modes)])
    }
  } else if (method %in% c("n", "nmodes")) {
    # Return the number of modes
    return(nmodes)
  } else if (method %in% c("all", "modes")) {
    # Return NA if no modes exist, else return all modes
    if (nmodes > 0) {
      return(ux[which(modes)])
    } else {
      return(NA)
    }
  }
  warning("Warning: method not recognised.  Valid methods are 'one'/'mode' [default], 'n'/'nmodes' and 'all'/'modes'")
}

Ken의 방법을 사용하여 주파수를 계산하기 때문에 성능도 최적화되었으므로 AkselA의 게시물을 사용하여 이전 답변 중 일부를 벤치마킹하여 내 기능이 Ken의 성능에 얼마나 근접한지를 보여주었습니다. 다양한 출력 옵션에 대한 조건은 약간의 오버 헤드 만 발생시킵니다. 모드 기능 비교


제시 한 코드 Modepracma패키지 에서 찾은 기능 의 다소간 간단한 사본으로 보입니다 . 설명 할까?
AkselA

정말? 분명히 이것이 이것이 모드를 계산하는 좋은 방법이라고 생각하는 유일한 사람은 아니지만 솔직히 그 사실을 몰랐습니다 (지금까지 그 패키지를 알지 못했습니다). 나는 Chris의 기능을 정리하고 Ken의 버전을 활용하여 개선했으며, 우연히 일치하는 다른 사람의 코드와 유사하다면.
hugovdberg

방금 살펴 봤지만 어떤 버전의 pracma패키지를 참조하십니까? 버전 1.9.3은 내가 볼 수있는 한 완전히 다른 구현을 가지고 있습니다.
hugovdberg

2
기능에 좋은 수정. 추가로 읽은 후에는 균일 또는 단일 주파수 분포에 노드가 있는지 여부에 대한 합의가 없다는 결론에 도달했습니다. 일부 소스는 모드 목록이 분포 자체라고 말하고 다른 소스는 노드가 없다고 말합니다. 유일한 합의는 그러한 배포판에 대한 모드 목록을 작성하는 것이 매우 유익하거나 특히 의미가 없다는 것입니다. 위의 함수가 이러한 경우에 모드를 생성하도록하려면 다음 줄을 제거하십시오. nmodes <-ifelse (nmodes == n, 0L, nmodes)
Chris

1
@greendiod 죄송합니다. 귀하의 의견을 놓쳤습니다. 그것은이 요점을 통해 볼 수 있습니다 : gist.github.com/Hugovdberg/0f00444d46efd99ed27bbe227bdc4d37
hugovdberg

6

이 핵은 잘 작동합니다. 모드 카운트뿐만 아니라 값을 제공합니다.

Mode <- function(x){
a = table(x) # x is a vector
return(a[which.max(a)])
}

3

R에는 애드온 패키지가 너무 많아 일부는 숫자 목록 / 계열 / 벡터의 [통계] 모드를 제공 할 수 있습니다.

그러나 R 자체의 표준 라이브러리에는 그러한 내장 방법이없는 것 같습니다! 이 문제를 해결하는 한 가지 방법은 다음과 같은 일부 구문을 사용하는 것입니다 (그리고 자주 사용하는 경우 이것을 함수로 설정하는 것입니다).

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이 자동으로 이것을 최적화한다는 것을 모르겠습니다)

참조 : "중간 및 모드는 어떻습니까?"를 참조하십시오. 이 킥 스타트 R 레슨에서
이것은 (적어도이 레슨을 쓰는 시점에서) R에 모드 함수가 없다는 것을 확인하는 것 같습니다 ).


3

이것은 꽤 잘 작동합니다

> a<-c(1,1,2,2,3,3,4,4,5)
> names(table(a))[table(a)==max(table(a))]

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)
}

3

다음은 R에서 벡터 변수의 모드를 찾는 데 사용할 수있는 코드입니다.

a <- table([vector])

names(a[a==max(a)])

3

이 솔루션에는 여러 가지 솔루션이 제공됩니다. 나는 첫 번째를 확인한 후 내 자신을 썼다. 도움이된다면 여기에 게시하십시오.

Mode <- function(x){
  y <- data.frame(table(x))
  y[y$Freq == max(y$Freq),1]
}

몇 가지 예를 통해 테스트 해 보겠습니다. 내가 복용하고 iris데이터 세트를. 숫자 데이터로 테스트 할 수 있습니다

> Mode(iris$Sepal.Length)
[1] 5

확인할 수 있습니다.

이제 홍채 데이터 세트 (종)의 숫자가 아닌 유일한 필드에는 모드가 없습니다. 우리 자신의 예제로 테스트합시다

> test <- c("red","red","green","blue","red")
> Mode(test)
[1] red

편집하다

주석에서 언급했듯이 사용자는 입력 유형을 유지하려고 할 수 있습니다. 이 경우 모드 기능을 다음과 같이 수정할 수 있습니다.

Mode <- function(x){
  y <- data.frame(table(x))
  z <- y[y$Freq == max(y$Freq),1]
  as(as.character(z),class(x))
}

함수의 마지막 줄은 최종 모드 값을 원래 입력 유형으로 강제 변환합니다.


이것은 사용자가 입력 유형을 유지하려고 할 때 인수를 반환합니다. 아마 중간 단계를 추가하십시오y[,1] <- sort(unique(x))
Frank

2

밀도 () 함수를 사용하여 (연속적인) 분포의 평활화 된 최대 값을 식별합니다.

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

여기서 x는 데이터 수집입니다. 스무딩을 조절하는 밀도 함수 의 조정 파레 미터에 주의 하십시오.


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)) )]
} 

길이가 1 인 하나의 모드가있는 경우 - 항상 목록을 반환하는 경우이 프로그램 사용에 일관성을 것입니다
ASAC

그것은 유효한 포인트 @ antoine-sac입니다. 이 솔루션에서 내가 좋아하는 것은 반환되는 벡터가 대답을 쉽게 처리 할 수있게 남겨 두는 것입니다. r [1] 및 r [2]에서 사용 가능한 모드로 r <-mode (c (2, 2, 3, 3)) 함수의 출력을 간단히 지정하십시오. 아직도, 당신은 좋은 지적을합니다!
RandallShanePhD

정확하게, 이것은 당신의 해결책이 부족한 곳입니다. 만약 mode복귀 여러 값리스트 후, r [1]은 첫 번째 값 아니다; 대신 첫 번째 값을 포함하는 길이 1의 목록이므로 첫 번째 모드를 목록이 아닌 숫자로 가져 오려면 r [[1]]을 수행해야합니다. 이제 단일 모드가있을 때 r은 목록이 아니므로 r [1]이 작동하므로 일관성이 없다고 생각합니다. 그러나 r이 간단한 벡터 일 때 r [[1]]도 작동하기 때문에 실제로 [[요소에 액세스 하는 데 항상 사용할 수 있다는 사실을 깨닫지 못한 일관성이 있습니다 .
asac

2

나는이 모든 옵션들을 살펴보면서 그들의 상대적인 특징과 성능에 대해 궁금해하기 시작했고, 몇 가지 테스트를했습니다. 다른 사람이 같은 것에 대해 궁금한 경우 여기에서 내 결과를 공유하고 있습니다.

여기에 게시 된 모든 함수를 신경 쓰지 않고 몇 가지 기준에 따라 샘플에 중점을 두었습니다. 함수는 문자, 요소, 논리 및 숫자 벡터 모두에서 작동해야하며 NA 및 기타 문제가있는 값을 적절하게 처리해야합니다. 그리고 출력은 '감각적'이어야합니다. 즉, 문자 나 다른 그런 어리 석음과 같은 숫자가 없어야합니다.

또한 rle더 일반적인 용도로 개조 된 것을 제외하고 chrispy 와 동일한 아이디어를 기반으로하는 내 자신의 기능을 추가했습니다 .

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

나는 두 세트의 테스트 데이터에서 5 개의 기능을 실행했습니다 microbenchmark. 함수 이름은 해당 저자를 나타냅니다.

여기에 이미지 설명을 입력하십시오

크리스 '기능으로 설정 method="modes"하고na.rm=TRUE 기본적으로 그 저자에 의해 여기에 제시된 기능이 사용 된 것보다하는 것이 더 비교하지만, 다른 만들 수 있습니다.

속도만으로도 Kens 버전이 손에 win지만, 실제로는 몇 개가 있더라도 하나의 모드 만보고하는 것도 유일한 방법입니다. 종종 그렇듯이 속도와 다양성 사이에는 절충점이 있습니다. 에서 method="mode"하나 개의 모드, 다른 NA가 IFF에, 크리스 '버전은 값을 반환합니다. 나는 그것이 좋은 터치라고 생각합니다. 또한 일부 기능이 고유 값의 수 증가에 의해 어떻게 영향을 받는지 흥미로운 반면 다른 기능은 그다지 많지 않습니다. 논리 / 숫자를 원인으로 제거하는 것 외에 그 이유를 파악하기 위해 코드를 자세히 연구하지 않았습니다.


2

모든 상황에서 모드가 유용한 것은 아닙니다. 따라서 기능은이 상황을 해결해야합니다. 다음 기능을 시도하십시오.

Mode <- function(v) {
  # checking unique numbers in the input
  uniqv <- unique(v)
  # frquency of most occured value in the input data
  m1 <- max(tabulate(match(v, uniqv)))
  n <- length(tabulate(match(v, uniqv)))
  # if all elements are same
  same_val_check <- all(diff(v) == 0)
  if(same_val_check == F){
    # frquency of second most occured value in the input data
    m2 <- sort(tabulate(match(v, uniqv)),partial=n-1)[n-1]
    if (m1 != m2) {
      # Returning the most repeated value
      mode <- uniqv[which.max(tabulate(match(v, uniqv)))]
    } else{
      mode <- "Two or more values have same frequency. So mode can't be calculated."
    }
  } else {
    # if all elements are same
    mode <- unique(v)
  }
  return(mode)
}

산출,

x1 <- c(1,2,3,3,3,4,5)
Mode(x1)
# [1] 3

x2 <- c(1,2,3,4,5)
Mode(x2)
# [1] "Two or more varibles have same frequency. So mode can't be calculated."

x3 <- c(1,1,2,3,3,4,5)
Mode(x3)
# [1] "Two or more values have same frequency. So mode can't be calculated."

죄송합니다. 이미 게시 된 내용에 새로운 기능이 어떻게 추가되는지 알 수 없습니다. 또한 출력이 위의 기능과 일치하지 않는 것 같습니다.
not2qubit

2

이것은 매우 짧은 벡터의 속도를 높여서 jprockbelly의 답변을 기반으로합니다. 이는 많은 소그룹으로 data.frame 또는 datatable에 모드를 적용 할 때 유용합니다.

Mode <- function(x) {
   if ( length(x) <= 2 ) return(x[1])
   if ( anyNA(x) ) x = x[!is.na(x)]
   ux <- unique(x)
   ux[which.max(tabulate(match(x, ux)))]
}

1

빈도별로 정렬 된 모든 값을 제공하는 또 다른 간단한 옵션은 다음을 사용하는 것입니다 rle.

df = as.data.frame(unclass(rle(sort(mySamples))))
df = df[order(-df$lengths),]
head(df)

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 

1

나는 당신의 관찰이 케이스 클래스 에서 실제 번호 와 당신이 기대 모드가 당신의 관찰 2, 2, 3, 3은 다음과 모드를 추정 할 수있는 경우 2.5 할 mode = l1 + i * (f1-f0) / (2f1 - f0 - f2)경우 L1 가장 빈번한 클래스의 ..lower 제한, F1을 . . 가장 빈번한 클래스의 빈도, f0 .. 가장 빈번한 클래스 이전의 클래스 빈도, f2 .. 가장 빈번한 클래스 이후의 클래스 빈도 및 i .. 1 , 2 , 3 에 주어진 클래스 간격 :

#Small Example
x <- c(2,2,3,3) #Observations
i <- 1          #Class interval

z <- hist(x, breaks = seq(min(x)-1.5*i, max(x)+1.5*i, i), plot=F) #Calculate frequency of classes
mf <- which.max(z$counts)   #index of most frequent class
zc <- z$counts
z$breaks[mf] + i * (zc[mf] - zc[mf-1]) / (2*zc[mf] - zc[mf-1] - zc[mf+1])  #gives you the mode of 2.5


#Larger Example
set.seed(0)
i <- 5          #Class interval
x <- round(rnorm(100,mean=100,sd=10)/i)*i #Observations

z <- hist(x, breaks = seq(min(x)-1.5*i, max(x)+1.5*i, i), plot=F)
mf <- which.max(z$counts)
zc <- z$counts
z$breaks[mf] + i * (zc[mf] - zc[mf-1]) / (2*zc[mf] - zc[mf-1] - zc[mf+1])  #gives you the mode of 99.5

당신이 원하는 경우에 가장 빈번한 레벨 가장 빈번한 레벨두 개 이상 보유한 과 같이 모든 레벨을 얻을 수 있습니다.

x <- c(2,2,3,5,5)
names(which(max(table(x))==table(x)))
#"2" "5"

1

가능한 data.table 접근법 추가

library(data.table)
#for single mode
dtmode <- function(x) x[which.max(data.table::rowid(x))]

#for multiple modes
dtmodes <- function(x) x[{r <- rowid(x); r==max(r)}]

1

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))

0

다음 기능을 시도 할 수 있습니다.

  1. 숫자 값을 인수로 변환
  2. frequency 테이블을 얻으려면 summary ()를 사용하십시오.
  3. 주파수가 가장 큰 인덱스를 반환 모드
  4. 하나 이상의 모드가 있더라도 변환 계수를 다시 숫자로 변환하면이 기능이 제대로 작동합니다!
mode <- function(x){
  y <- as.factor(x)
  freq <- summary(y)
  mode <- names(freq)[freq[names(freq)] == max(freq)]
  as.numeric(mode)
}

0

계산 모드는 주로 요인 변수의 경우 사용할 수 있습니다

labels(table(HouseVotes84$V1)[as.numeric(labels(max(table(HouseVotes84$V1))))])

HouseVotes84는 'mlbench'패키지로 제공되는 데이터 세트입니다.

최대 레이블 값을 제공합니다. 함수를 작성하지 않고 내장 함수 자체로 사용하기가 더 쉽습니다.


0

컬렉션에 모드가있는 경우 해당 요소를 자연수와 일대일로 매핑 할 수있는 것 같습니다. 따라서 모드를 찾는 문제는 이러한 매핑을 생성하고 매핑 된 값의 모드를 찾은 다음 컬렉션의 일부 항목에 다시 매핑하는 것으로 줄어 듭니다. ( NA매핑 단계에서 처리 ).

histogram비슷한 주체에서 작동 하는 기능이 있습니다. (여기에 제시된 코드에 사용 된 특수 기능과 연산자는 Shapiro 및 / 또는 neatOveRse에 정의되어야합니다 . 여기에 복제 된 Shapiro 및 neatOveRse 부분은 허가를 받아 복제 된 것이므로 중복 된 스 니펫은이 사이트의 조건에 따라 사용될 수 있습니다. ) R의 의사 코드 에 대한 histogramIS

.histogram <- function (i)
        if (i %|% is.empty) integer() else
        vapply2(i %|% max %|% seqN, `==` %<=% i %O% sum)

histogram <- function(i) i %|% rmna %|% .histogram

(특수 이진 연산자는 pipeing , curryingcomposition을 달성합니다 ) 또한 maxloc비슷한 함수를 가지고 which.max있지만 벡터의 절대 최대 값을 모두 반환 합니다 . R의 의사 에 대한 maxlocIS

FUNloc <- function (FUN, x, na.rm=F)
        which(x == list(identity, rmna)[[na.rm %|% index.b]](x) %|% FUN)

maxloc <- FUNloc %<=% max

minloc <- FUNloc %<=% min # I'M THROWING IN minloc TO EXPLAIN WHY I MADE FUNloc

그때

imode <- histogram %O% maxloc

x %|% map %|% imode %|% unmap

적절한 map-ping 및 unmap-ping 기능이 정의 된 경우 모든 콜렉션의 모드를 계산합니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.