programing

통계 모드를 찾는 방법은 무엇입니까?

skycolor 2023. 6. 26. 21:11
반응형

통계 모드를 찾는 방법은 무엇입니까?

R에서,mean()그리고.median()표준 기능을 사용하여 예상한 대로 작동합니다. mode()개체의 인수에서 가장 많이 발생하는 값이 아니라 개체의 내부 저장 모드를 알려줍니다.그러나 벡터(또는 목록)에 대한 통계 모드를 구현하는 표준 라이브러리 함수가 있습니까?

숫자 및 문자/요인 데이터 모두에 적용되는 솔루션이 하나 더 있습니다.

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

제 작은 기계에서, 그것은 약 0.5초 만에 10M 정수 벡터의 모드를 생성하고 찾을 수 있습니다.

데이터 세트에 여러 모드가 있을 수 있는 경우 위의 솔루션은 다음과 같은 방법을 사용합니다.which.max모드 집합의 첫 번째 값을 반환합니다.모든 모드를 반환하려면 이 변형 모델(@digEm에서)을 사용합니다.모든 의견):

Modes <- function(x) {
  ux <- unique(x)
  tab <- tabulate(match(x, ux))
  ux[tab == max(tab)]
}

패키지가 있습니다.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")

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

CRAN 작업 보기: 확률 분포에서 "모드 추정"을 찾을 수도 있습니다.두 가지 새로운 패키지가 제안되었습니다.

메일링 리스트에서 이것을 발견했습니다. 도움이 되길 바랍니다.그것은 또한 제가 어쨌든 생각하고 있던 것입니다.데이터를 표로 작성하고 정렬한 다음 이름을 선택합니다.구식이지만 효과가 있을 겁니다.

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

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

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

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

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

방법 = "mode" [default]: 단모달 벡터에 대한 모드를 계산합니다. 그렇지 않으면 NA를 반환합니다.
방법 = "nmodes": 벡터의 모드 수를 계산합니다.
방법 = "module": 단모달 또는 다모달 벡터에 대한 모든 모드를 나열합니다.

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

여기, 또 다른 해결책이 있습니다.

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

저는 아직 투표할 수 없지만 라스무스 보오스의 대답은 제가 찾던 것입니다.그러나 예를 들어 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)]
}

분포를 전혀 제한하지 않고 =-"B"로 설정할 수도 있음을 알고 있습니다.IG NUMBER", ="B"에 연결IG 번호"

모드 또는 관련 메트릭을 계산하는 @Chris의 함수를 기반으로 하지만 주파수를 계산하는 Ken Williams의 방법을 사용합니다. 없는 합니다. (자주 발생합니다.) 좀 더 읽기 쉬운 이것은모 해 요 동 에 하 게 자 일 주 발 생 가 쉽 제 읽 니 습 다 더 일 기 고 하 을 는 대 한 부 공 결 책 든 우 경 소 모 드 는 가 없혀 전 ▁thismethod

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과 얼마나 유사한지 보여주기 위해 이전 답변 중 일부를 벤치마킹했습니다.

인 함수는 다음과 .fmode에 시대에collapse이제 CRAN에서 사용할 수 있는 패키지는 인덱스 해싱을 기반으로 C++ 기반 모드를 구현합니다.위의 접근 방식보다 훨씬 빠릅니다.벡터, 행렬, data.frame 및 dplyr 그룹화된 경골에 대한 메서드가 함께 제공됩니다.구문:

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

x의 개체 중 일 수 .g그룹화 벡터 또는 그룹화 벡터 목록(그룹화 모드 계산의 경우, C++에서도 수행됨)을 제공합니다.w(선택 사항) 숫자 가중치 벡터를 제공합니다.에는 이 없습니다.g논쟁, 당신은 할 수 있습니다.data %>% group_by(idvar) %>% fmode.

인 params Ken Williams를 .na.rm그리고.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])
}

옵션 파라미터와 함께 작동하고 데이터 유형을 유지 관리하는 방법을 보여줍니다.

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의 단순화에 감사드립니다.

모드를 생성하기 위해 다음 코드를 작성했습니다.

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)

이 해킹은 잘 될 겁니다.값과 모드 카운트를 제공합니다.

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

이것은 매우 짧은 벡터에 대한 속도 향상을 추가함으로써 jprocbely의 답변을 기반으로 합니다.이 기능은 모드를 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)))]
}

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에 모드 기능이 없다는 것을 확인하는 것처럼 보입니다.mode(모드)는 변수 유형을 주장하는 데 사용됩니다.

이것은 꽤 잘 작동합니다.

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

모드를 찾는 기능은 다음과 같습니다.

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

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

a <- table([vector])

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

이 솔루션에는 여러 솔루션이 제공됩니다.저는 첫 번째 것을 확인하고 그 후에 저 자신의 것을 썼습니다.도움이 되는 사람이 있다면 여기에 게시:

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

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

주파수별로 정렬된 모든 값을 제공하는 또 다른 간단한 옵션은 다음과 같습니다.rle:

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

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

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

여기서 x는 데이터 수집입니다.평활화를 조절하는 밀도 함수의 조정 매개 변수에 주의하십시오.

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

저는 이 모든 옵션들을 살펴보던 중 그들의 상대적인 특징과 성능에 대해 궁금해하기 시작했고, 그래서 몇 가지 테스트를 했습니다.혹시 다른 분들도 궁금하실까봐 제 결과를 여기에 공유해드립니다.

여기에 게시된 모든 함수에 대해 신경 쓰고 싶지 않기 때문에 몇 가지 기준에 따라 샘플에 초점을 맞추기로 했습니다. 함수는 문자, 요인, 논리 및 숫자 벡터 모두에서 작동해야 하고, 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

두 의 테스트 데이터 의 함수를 했습니다.microbenchmark함수 이름은 각 작성자를 나타냅니다.

enter image description here

은 Chris 기능다같설었습니다되정이의과음으로 설정되었습니다.method="modes"그리고.na.rm=TRUE기본적으로 비교 가능하도록 만들지만, 작성자가 여기에 제시한 기능을 제외하고는 기능이 사용되었습니다.

속도만 놓고 보면 Kens 버전이 쉽게 이기지만, 실제로 수가 얼마나 많든 간에 하나의 모드만 보고하는 유일한 버전이기도 합니다.흔히 있는 일이지만 속도와 다용도성 사이에는 균형이 있습니다.method="mode"Chris 버전은 하나의 모드(NA)가 있으면 값을 반환합니다.좋은 터치인 것 같아요.저는 또한 일부 기능이 증가된 고유 값의 수에 의해 영향을 받는 반면 다른 기능은 거의 영향을 받지 않는 것이 흥미롭다고 생각합니다.원인이 되는 논리적/숫자를 제거하는 것 외에 그 이유를 알아내기 위해 코드를 자세히 연구하지 않았습니다.

모드가 모든 상황에서 유용할 수는 없습니다.따라서 기능은 이 상황을 해결해야 합니다.다음 기능을 사용해 보십시오.

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

또 다른 가능한 해결책:

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 

관측치가 실수의 클래스이고 관측치가 2, 2, 3 및 3일 때 모드가 2.5일 것으로 예상하는 경우, 다음을 사용하여 모드를 추정할 수 있습니다.mode = l1 + i * (f1-f0) / (2f1 - f0 - f2)여기서 나는..가장 빈번한 수업의 하한, 가장 빈번한 수업의 빈도, 가장 빈번한 수업의 빈도, 가장 빈번한 수업의 빈도, 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"

의 내장 물어본다면, 패키지 R 물 패 찾 수 것 다 입 니 있 을 에 을 서 에 키 내 장 지 된 기 능 면 을 보 어 ▁r 니 ▁if ▁you 다 ▁package ▁in▁it ▁find 입 것 ▁on ▁can ▁the ▁maybe ▁r 내 - 있 장 , 에pracma에는 그패지안다음같있기다습니능이은라는 기능이 .Mode.

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

  1. 숫자 값을 요인으로 변환
  2. summary()를 사용하여 빈도 표를 얻습니다.
  3. 반환 모드 빈도가 가장 큰 인덱스
  4. 하나 이상의 모드가 있더라도 인자를 숫자로 다시 변환합니다. 이 기능은 잘 작동합니다!
mode <- function(x){
  y <- as.factor(x)
  freq <- summary(y)
  mode <- names(freq)[freq[names(freq)] == max(freq)]
  as.numeric(mode)
}

계산 모드는 대부분 요인 변수의 경우에 사용됩니다.

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

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

최대 레이블 값을 제공합니다.쓰기 기능 없이 내장된 기능 자체로 더 쉽게 사용할 수 있습니다.

raster::modal() 선사항으로참, 나고로그러택참▁that.raster무거운 패키지이므로 지리 공간 작업을 수행하지 않으면 설치할 가치가 없을 수 있습니다.

소스 코드는 https://github.com/rspatial/raster/blob/master/src/modal.cpp 과 https://github.com/rspatial/raster/blob/master/R/modal.R 에서 개인 R 패키지로 추출할 수 있습니다.

언급URL : https://stackoverflow.com/questions/2547402/how-to-find-the-statistical-mode

반응형