【问题标题】:Split vector such that means of two groups are nearly equal分裂向量,使得两组的平均值几乎相等
【发布时间】:2012-01-15 08:58:43
【问题描述】:

我有一个数据框 df 有 2 个变量 A 和 B。我想将 A 拆分为第 1 组和第 2 组,以便 mean(df$B[df$group==1]) 尽可能接近 mean(df$B[df$group==2])

或者只是为了表达它,我想在df$A中找到一个切点(cutp),以最小化abs(mean(df$B[df$A<cutp])-mean(df$B[df$A>=cutp]))

有什么想法吗?

【问题讨论】:

  • 第 1 组和第 2 组是否必须相等?
  • 感谢您的评论。第 1 组和第 2 组的病例数应该大致相同(或至少没有大的差异)。
  • 变量 A 在问题中是否起任何作用?
  • 我不明白你的评论文森特。
  • 您的 data.frame 包含两列,A 和 B,并且您写要“拆分 A”(而不是“拆分 df”)为两组,这表明应该使用列 A在分裂中——然而,它并没有明确地出现在你的条件中。

标签: r


【解决方案1】:

如果你想在变量 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" )

【讨论】:

  • 是的,就是这样。非常感谢。
【解决方案2】:

我仍然不确定 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 设置为超低,您可能会创建一个失控函数,所以如果您的计算机崩溃了,请不要怪我。

【讨论】:

    猜你喜欢
    • 2019-02-12
    • 2020-06-22
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多