R에서, mean()
그리고 median()
당신이 기대하는 일을 표준 기능은 다음과 같습니다. mode()
인수에서 가장 많이 발생하는 값이 아니라 객체의 내부 저장 모드를 알려줍니다. 그러나 벡터 (또는 목록)에 대한 통계 모드를 구현하는 표준 라이브러리 함수가 있습니까?
mode
함수와 같은 것으로 간주 class
합니까?
R에서, mean()
그리고 median()
당신이 기대하는 일을 표준 기능은 다음과 같습니다. mode()
인수에서 가장 많이 발생하는 값이 아니라 객체의 내부 저장 모드를 알려줍니다. 그러나 벡터 (또는 목록)에 대한 통계 모드를 구현하는 표준 라이브러리 함수가 있습니까?
mode
함수와 같은 것으로 간주 class
합니까?
답변:
숫자 및 문자 / 인자 데이터 모두에 사용할 수있는 또 하나의 솔루션 :
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)]
}
c(1,1,2,2)
. 마지막 줄을 다음과 같이 변경해야합니다.tab <- tabulate(match(x, ux)); ux[tab == max(tab)]
ux[which.max(tabulate(match(x, ux)))]
just로 대체 할 것 max(tabulate(match(x, ux)))
입니다.
Mode(1:3)
제공 1
하고 Mode(3:1)
있습니다 3
그들 모두가 고유 모드 인 경우가 가장 흔한 요소 또는 첫 번째를 반환, 그래서.
0
되거나 NA
그 경우 에 훨씬 좋았을 것 입니다.
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")
mfv(mySamples)[1]
. 1
실제로 가장 빈번한 값 반환으로 중요한 존재 들 .
mfv(mySamples)
r 메일 링리스트에서이 정보를 찾았 으면 도움이 되길 바랍니다. 어쨌든 내가 생각했던 것이기도합니다. 데이터를 table ()하고 정렬 한 다음 이름을 선택합니다. 그것은 hackish이지만 작동해야합니다.
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
set.seed(1); a<-runif(100); mode<-density(a)$x[which.max(density(a)$y)]; abline(v=mode)
error in density.default(x, from = from, to = to) : need at least 2 points to select a bandwidth automatically
density
. 그러나 하나의 데이터 포인트 만 있다면 해당 데이터 포인트의 값은 아마도 어쨌든 모드에 대한 최선의 추측 일 것입니다.
estimate_mode <- function(x) { if (length(x)>1){ d <- density(x) d$x[which.max(d$y)] }else{ x } }
. 원형 패키지에 벡터 평균을 사용하는 방향 대신 평균 방향 바람을 추정하는 방법을 테스트하고 있습니다. 다각형 등급 이상의 점으로 작업하므로 방향이있는 점이 하나만있는 경우가 있습니다. 감사!
다음 기능은 세 가지 형태로 제공됩니다.
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()
}
method = 'modes'
. 그런 다음이 함수는 모든 고유 값을 반환하지만 실제로는 모드가 없으므로 NA
대신 반환해야 합니다. 영감을 얻은 덕분에 약간 최적화 된 버전의 함수가 포함 된 다른 답변을 추가 할 것입니다!
또 다른 해결책은 다음과 같습니다.
freq <- tapply(mySamples,mySamples,length)
#or freq <- table(mySamples)
as.numeric(names(freq)[which.max(freq)])
아직 투표를 할 수 없지만 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
선택적 매개 변수 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에게 감사합니다.
모드를 생성하기 위해 다음 코드를 작성했습니다.
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)
@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의 성능에 얼마나 근접한지를 보여주었습니다. 다양한 출력 옵션에 대한 조건은 약간의 오버 헤드 만 발생시킵니다.
Mode
는 pracma
패키지 에서 찾은 기능 의 다소간 간단한 사본으로 보입니다 . 설명 할까?
pracma
패키지를 참조하십니까? 버전 1.9.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에 모드 함수가 없다는 것을 확인하는 것 같습니다 ).
모드를 찾는 기능은 다음과 같습니다.
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)
}
이 솔루션에는 여러 가지 솔루션이 제공됩니다. 나는 첫 번째를 확인한 후 내 자신을 썼다. 도움이된다면 여기에 게시하십시오.
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))
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)) )]
}
mode
복귀 여러 값리스트 후, r [1]은 첫 번째 값 아니다; 대신 첫 번째 값을 포함하는 길이 1의 목록이므로 첫 번째 모드를 목록이 아닌 숫자로 가져 오려면 r [[1]]을 수행해야합니다. 이제 단일 모드가있을 때 r은 목록이 아니므로 r [1]이 작동하므로 일관성이 없다고 생각합니다. 그러나 r이 간단한 벡터 일 때 r [[1]]도 작동하기 때문에 실제로 [[
요소에 액세스 하는 데 항상 사용할 수 있다는 사실을 깨닫지 못한 일관성이 있습니다 .
나는이 모든 옵션들을 살펴보면서 그들의 상대적인 특징과 성능에 대해 궁금해하기 시작했고, 몇 가지 테스트를했습니다. 다른 사람이 같은 것에 대해 궁금한 경우 여기에서 내 결과를 공유하고 있습니다.
여기에 게시 된 모든 함수를 신경 쓰지 않고 몇 가지 기준에 따라 샘플에 중점을 두었습니다. 함수는 문자, 요소, 논리 및 숫자 벡터 모두에서 작동해야하며 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에, 크리스 '버전은 값을 반환합니다. 나는 그것이 좋은 터치라고 생각합니다. 또한 일부 기능이 고유 값의 수 증가에 의해 어떻게 영향을 받는지 흥미로운 반면 다른 기능은 그다지 많지 않습니다. 논리 / 숫자를 원인으로 제거하는 것 외에 그 이유를 파악하기 위해 코드를 자세히 연구하지 않았습니다.
모든 상황에서 모드가 유용한 것은 아닙니다. 따라서 기능은이 상황을 해결해야합니다. 다음 기능을 시도하십시오.
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)
경우 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"
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))
계산 모드는 주로 요인 변수의 경우 사용할 수 있습니다
labels(table(HouseVotes84$V1)[as.numeric(labels(max(table(HouseVotes84$V1))))])
HouseVotes84는 'mlbench'패키지로 제공되는 데이터 세트입니다.
최대 레이블 값을 제공합니다. 함수를 작성하지 않고 내장 함수 자체로 사용하기가 더 쉽습니다.
컬렉션에 모드가있는 경우 해당 요소를 자연수와 일대일로 매핑 할 수있는 것 같습니다. 따라서 모드를 찾는 문제는 이러한 매핑을 생성하고 매핑 된 값의 모드를 찾은 다음 컬렉션의 일부 항목에 다시 매핑하는 것으로 줄어 듭니다. ( NA
매핑 단계에서 처리 ).
histogram
비슷한 주체에서 작동 하는 기능이 있습니다. (여기에 제시된 코드에 사용 된 특수 기능과 연산자는 Shapiro 및 / 또는 neatOveRse에 정의되어야합니다 . 여기에 복제 된 Shapiro 및 neatOveRse 부분은 허가를 받아 복제 된 것이므로 중복 된 스 니펫은이 사이트의 조건에 따라 사용될 수 있습니다. ) R의 의사 코드 에 대한 histogram
IS
.histogram <- function (i)
if (i %|% is.empty) integer() else
vapply2(i %|% max %|% seqN, `==` %<=% i %O% sum)
histogram <- function(i) i %|% rmna %|% .histogram
(특수 이진 연산자는 pipeing , currying 및 composition을 달성합니다 ) 또한 maxloc
비슷한 함수를 가지고 which.max
있지만 벡터의 절대 최대 값을 모두 반환 합니다 . R의 의사 에 대한 maxloc
IS
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 기능이 정의 된 경우 모든 콜렉션의 모드를 계산합니다 .