2

我正在寻找一种将数据框拆分为大小相等的组(每组中的行数基本相同)的方法,这些组的平均值几乎相等。

User Data
1 5.0
2 4.5
3 3.5
4 6.0
5 7.0
6 6.5
7 5.5
8 6.2
9 5.7
10 5.9

这与此请求非常相似, 但是这只会将数据分成 2 组。

我的实际数据集包含 75-150 行,我需要将其拆分为 5-10 个均值相等且大小相当的组。

过去几天我研究了 Google 和 Stack Exchange,但运气不佳。任何指导都会很棒。

提前致谢!

更多细节:

也许我需要提供更多细节,下面我已经包含了一个真实的数据集。我们是一家运输公司,该数据集提供了 Driver ID、Miles、Gallons。我一直在做的是将数据读入 R,并添加 MPG 列,如下所示:

data <- read.csv('filename')  
data$MPG <- data$Miles / data$Gallons

然后我尝试了下面提供的两个答案。Arun 的想法给了我几乎相等的组大小(每组 9 个成员,10 个组),但是平均值的变化很大,从 6.615 到 7.093,这对我来说太大了,无法开始。Thomas 的想法变得更紧凑一些,但小组规模都不同,只有 6 到 13 名成员。

我们要做的是提高车队的 MPG,我们将通过基于团队的比赛来实现这一点,所以我需要从相对相同的组 MPG 开始将所有团队随机放在一起。

也许这有助于并且可以引导我们朝着正确的方向前进?我尝试只用我的编程语言来做这件事,但它每次都会锁定计算机,所以我认为 R 可能能够更好地处理数据。

再次感谢!

4

3 回答 3

3

按照 Thomas 的想法,这是一种蛮力/贪婪方法,它会给出或多或少相同的值(您可以选择更多重复,直到您同意解决方案的接近性)。

# Assuming the data you provided is in `df`
grp <- 5
myfun <- function() {
    samp <- sample(nrow(df))
    s.mean <- tapply(df$Data, samp %% grp, mean)
    s.var <- var(s.mean)
    list(samp, s.mean, s.var)
}
out <- replicate(1000, myfun(), simplify=FALSE)
min.pos <- which.min(sapply(out, `[[`, 3))
min.idx <- out[[min.pos]][[1]]
split(df$Data[min.idx], min.idx %% grp)

$`0`
[1] 7.0 5.9

$`1`
[1] 5.0 6.5

$`2`
[1] 5.5 4.5

$`3`
[1] 6.2 3.5

$`4`
[1] 5.7 6.0

这是out[min.pos]这样的:

out[min.pos]

[[1]]
[[1]][[1]]
 [1]  7  9  8  5  3  4  1  2 10  6

[[1]][[2]]
   0    1    2    3    4 
5.85 5.70 5.60 5.25 5.50 

[[1]][[3]]
[1] 0.05075
于 2013-07-05T22:48:47.287 回答
3

如果相似的均值真的很重要,我在下面汇总了一个模拟,该模拟基本上查看n了特定组大小( )的一组不同的数据组合( k),然后最小化组均值的方差。通过该最小化,您可以从模拟结果中提取该分组。

df <- data.frame(User=1:1000,Data=rnorm(1000,0,1))     # example data
myfun = function(){
    k <- 5                                             # number of groups
    tmp <- seq(length(mpg))%%ngroups                   # really efficient code from @qwwqwwq's answer
    thisgroup <- sample(tmp, dim(df)[1], FALSE)        # pull a sample
    # thisgroup <- sample(1:k,dim(df)[1],TRUE)         # original version
    thisavg <- as.vector(by(df$Data, thisgroup, mean)) # group means
    thisvar <- var(thisavg)                            # variance of means
    return(list(group=thisgroup, avgs=thisavg, var=thisvar))
}
n <- 1000 # number of simulations
sorts <- replicate(n, myfun(), simplify=FALSE)
wh <- which.min(sapply(sorts, function(x) x$var))      # minimization
# sorts[[wh]]                   # this is the sample you want
split(df, sorts[[wh]]$group)    # list of separate dataframes for each group

你也可以有k不同的大小,如果你不关心每个组中有多少案例,只需将k <- 5线移动到函数中并让它从你愿意拥有的组数范围内随机抽取.

不过,可能还有其他方法可以做到这一点。

于 2013-07-05T22:32:39.670 回答
1

我能想到的最简单的方法:对数据进行排序,将所有指标按组数取模,然后就完成了。如果数据是正态分布的,我认为应该可以正常工作。具有尽可能相同大小的组的优势。

mpg <- rnorm(150)
mpg <- sort(mpg)
ngroups = 13
df = data.frame( mpg=mpg, group=seq(length(mpg))%%ngroups)
tapply(df$mpg, df$group, mean)

           0            1            2            3            4            5            6            7            8 
 0.080400272 -0.110797283 -0.046698548 -0.014177675  0.024410834  0.048370962  0.066265303  0.087119914 -0.062259638 
           9           10           11           12 
-0.042172496 -0.003451581  0.033853024  0.056947458 
于 2013-07-09T16:57:40.907 回答