2017-11-10 9 views
3

問題:2つのグループ(Nout)間の完全な分離を達成するために除去される観察の最小数をRで計算する。2つのグループ間で完全な分離可能性を達成するために除去される観察の最小数を計算する方法

例:

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の2つの上位値とbの下位3つの値を削除すると、Nout = 2 + 3 = 5となる可能性のある解が得られます。 これは、たとえば6.2のしきい値に相当します)

自動的に簡単に計算するためのRツールはありますか?

IはRアーカイブ2つの同様のツールが見つかりました:

彼らは検証されていないようです(コードは「保証なし」で始まり、アクティブなパッケージリストにはありません)

答えて

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 
関連する問題