2017-11-10 2 views
3

문제점 : R에서 두 그룹 (Nout) 간의 완전한 분리를 위해 제거 할 최소 관측 수를 계산합니다.두 그룹 사이의 완전한 분리를 위해 제거 할 최소 관측 수를 계산하는 방법

예 :

df<-data.frame(c(1,2,3,4,5,6,7,10,4,5.5,6,6.5,8,9,12),c(rep("a",8),rep("b",7))) 
colnames(df)<-c("Values","Groups") 
df 
boxplot(df[,1]~df[,2]) 
points(df[,1]~df[,2],cex=2) 
abline(6.2,0) 

See the plot produced with the above code here.

그런 경우, b의 3 개의 가장 낮은 값과 a의 2 개의 더 높은 값을 제거하면 Nout = 2 + 3 = 5 인 가능한 솔루션이 제공됩니다. 예를 들어 임계 값 6.2에 해당합니다 (플롯의 빨간색 선)

자동으로 쉽게 자동으로 계산할 수있는 R 도구가 있습니까?

나는 R 아카이브에 2 유사한 도구를 발견

그들은 유효성이 검증되지 않은 것 같습니다 (코드는 "무보증"으로 시작하고 활성 R 패키지 목록에 없습니다)

답변

0

median이 유용하다고 생각하지만 일반적으로 3 가지 경우에 따라 다르게 적용해야합니다. 당신이 다른 경우에 median을 적용해야합니다 어떻게

case 1: distribution of values do not overlap 
case 2: distribution of values in 1 group completely overlaps with distribution of values in other group 
case 3: distribution of values partially overlap (the data example you gave) 

가 발생할 것이다 것은

case 1: median value of all values 
case 2: median value of all values 
case 3: median value of only overlapping values 

귀하의 데이터와 그래프 기능

다음
plotfun <- function(df) { 
    with(df, boxplot(Values~Groups)) 
    with(df, points(Values~Groups, cex=2)) 
} 

df<-data.frame(Values = c(1,2,3,4,5,6,7,10,4,5.5,6,6.5,8,9,12), 
      Groups = c(rep("a",8),rep("b",7))) 
df 
plotfun(df) 

주력 기능은 myfun입니다. 3 가지 사례 중 어느 것이 관련이 있는지를 결정한 다음 이에 따라 중앙값을 적용합니다. 값이 정수가 아닌 경우에 대비하여 추가 인수 unitofchange을 제공 할 수 있습니다. 즉, 0.1 씩 증가하는 데이터를 처리하고있는 것일 수 있습니다.

library(dplyr) 
myfun <- function(df, unitofchange=1) { 
    unitofchange <- unitofchange/10 
    require(dplyr) 
    summarydf <- df %>% 
      group_by(Groups) %>% 
      summarise(min = min(Values), max = max(Values)) %>% 
      arrange(min) 

    if (summarydf$max[1] < summarydf$min[2]) { 
     # Case 1: distributions do not overlap 
     ans <- list(Break = median(df$Values), Nout = 0) 
    } else if (summarydf$max[1] > summarydf$max[2]) { 
     # Case 2: one distribution is completely between other distribution 
     ans <- list(Break = median(df$Values)) 
     ans[["Break"]] <- modifyiftie(df, unitofchange, ans[["Break"]]) 
     ans["Nout"] <- sum(df$Values < ans[["Break"]]) 
    } else { 
     # Case 3: distributions partially overlap 
     subset_df <- df %>% 
       filter(between(Values, summarydf$min[2], summarydf$max[1])) 
     ans <- list(Break = median(subset_df$Values)) 
     ans[["Break"]] <- modifyiftie(df, unitofchange, ans[["Break"]]) 
     ans["Nout"] <- sum(subset_df$Values[subset_df$Groups == summarydf$Groups[1]] > ans[["Break"]], 
        subset_df$Values[subset_df$Groups == summarydf$Groups[1]] < ans[["Break"]]) 
    } 
    return(ans) 
} 

은 또한 분리 값이 두 그룹 모두에서 발견된다 당신이 준 예와 같은 경우에 다른 함수 modifyiftie를 포함 3 가지 경우

사례 3의

modifyiftie <- function(df, unitofchange, b) { 
    require(dplyr) 
    tie <- df %>% 
     group_by(Groups) %>% 
     filter(Values == b) 

    if (nrow(tie) > 0 & all(unique(tie$Groups) %in% unique(df$Groups))) {  # tie is true 
     return(b + unitofchange) 
    } else { 
     return(b) 
    } 
} 

출력 : 귀하의 데이터

df<-data.frame(Values = c(1,2,3,4,5,6,7,10,4,5.5,6,6.5,8,9,12), 
      Groups = c(rep("a",8),rep("b",7))) 
df 
myfun(df) 

# $Break 
# [1] 6.1 

# $Nout 
# [1] 5 

사례 1 : 배포판이 비어 있지 않습니다.

set.seed(1) 
df<-data.frame(Values = c(runif(10)*10, (runif(10)*10)+10), 
      Groups = rep(c("a","b"), each=10)) 
plotfun(df) 
myfun(df) 

# $Break 
# [1] 10.60616 

# $Nout 
# [1] 0 

케이스 2 rlap : 한 그룹의 분포가 다른 그룹의 유통 사이에 빠진다

set.seed(1) 
df<-data.frame(Values = c((runif(10)*5)+5, runif(10)*20), 
      Groups = rep(c("a","b"), each=10)) 
plotfun(df) 
myfun(df) 

# $Break 
# [1] 8.22478 

# $Nout 
# [1] 10 
관련 문제