我有一个包含2个变量A和B的数据框df
。我想在第1组和第2组中拆分A,以便mean(df$B[df$group==1])
尽可能接近mean(df$B[df$group==2])
或者只是为了表达它,我想要的是在cutp
中找到一个能够最小化df$A
abs(mean(df$B[df$A<cutp])-mean(df$B[df$A>=cutp]))
)
有什么想法吗?
答案 0 :(得分:4)
如果要在变量A上找到阈值,要将数据拆分为两组,以便这两组中B的均值相似,可以为所有可能的切点计算这些均值,并检查何时这些手段之间的距离很小。
# Sample data
n <- 10
d <- data.frame(
A = rnorm(n),
B = rnorm(n)
)
# The quantity to minimize
# (You can use a loop instead of apply.)
d$differences <- apply(
d, 1,
# Compute the difference of the means for each value of A
function (u) {
i <- d$A <= u[1];
abs( mean( d$B[which(i)]) - mean(d$B[which(!i)] ) )
}
)
# The mean of an empty vector is NaN: discard those values
d$differences[ ! is.finite( d$differences ) ] <- Inf
# Take the minimum
threshold <- d$A[ which.min( d$differences ) ]
# Build the groups
d$group <- ifelse( d$A <= threshold, "group 1", "group 2" )
答案 1 :(得分:1)
我仍然不确定A列如何影响它。您似乎想要创建一个具有两个级别的新列,这两个级别为列B创建〜=平均值。列A显然与创建的新列相关联,但不会直接影响所需的计算。我错过了什么吗?
无论如何,这是一个开始(请注意,这可以更加健壮,但概念验证应该有效)。定义一个你认为可以接受的容差,然后设置一个while循环来创建新的组,直到满足条件,即
FUN <- function(tol){
df$groups <- sample(1:2, nrow(df), TRUE)
while(abs(mean(df$B[df$groups == 1]) - mean(df$B[df$groups == 2])) > tol) {
df$groups <- sample(1:2, nrow(df), TRUE)
}
return(df)
}
set.seed(101)
df <- data.frame(A=runif(20),B=runif(20))
#Test it. Means should be less than .02 different and have roughly equivalent sample sizes.
set.seed(101)
out <- FUN(.02)
library(plyr)
> ddply(out, "groups", summarize, n = length(B), mean = mean(B))
groups n mean
1 1 11 0.5229024
2 2 9 0.5037279
我应该注意,如果你设置tol
超低,你可以创建一个失控功能,所以如果你的计算机崩溃,不要怪我。