如何将大型数据帧拆分为大约的较小部分。等长,这样一些具有相同 id
的行就不会落入下一部分。
这里是一些玩具数据:
x <- data.frame(id=c(rep(1,3),rep(2,2),rep(3,3),rep(4,2)),r1=rep(1,10),r2=rep(2,10))
那么如何将上面的 df 拆分成大约。相等大小的 df(df 列表)以便 id
保持不变?
期望的输出:在这里我们将 x 分成大约。 3等份
[1]
id r1 r2
1 1 1 2
2 1 1 2
3 1 1 2
[2]
id r1 r2
4 2 1 2
5 2 1 2
9 4 1 2
10 4 1 2
[3]
id r1 r2
6 3 1 2
7 3 1 2
8 3 1 2
EDIT 1 假设我们拆分了 x
以便每个部分包含大约。 3 行原始 df。所以这就是我**不想要的:
seqrow <- seq(1,nrow(x),3)
splts <- rep_len(1:length(seqrow), nrow(x))
lstdf <- split(x, f=splts)
lstdf
$`1`
id r1 r2
1 1 1 2
5 2 1 2
9 4 1 2
$`2`
id r1 r2
2 1 1 2
6 3 1 2
10 4 1 2
$`3`
id r1 r2
3 1 1 2
7 3 1 2
$`4`
id r1 r2
4 2 1 2
8 3 1 2
所以我们这里有最大值。每个 df 有 3 行,但我们看到 id's
分别分散在每个部分。
最佳答案
我假设您估计了每个子集中的预期行数,即 bin。
以下代码开始填充容器,从最大的 id 子集开始。然后将仍然适合的 id-subsets 连续添加到 bin 中,直到达到 bin 中的最大行数。
x <- data.frame(id=c(rep(1,2),rep(2,2),rep(3,3),rep(4,2)),r1=rep(1,9),r2=rep(2,9))
splitDfId <- function(
### Split dataframe into subsets,
### keeping rows with same identifier together
x ##<< dataframe to split
,id ##<< factor so that lines of equal level are grouped into the same subsets
,maxBinSize=4 ##<< number of rows in each subset
){
dfCntBin <- data.frame(cnt=sort(table(id), decreasing =TRUE), bin=0L )
# bins must be as big as the maximum number of equal level
maxBinSize <- max( dfCntBin$cnt, maxBinSize)
#
toBin <- 1:nrow(dfCntBin)
while( length(toBin) > 0 ){
binNr <- max(dfCntBin$bin)+1
binCnt <- 0
# first entry in toSort is the first matching entry
# matching: still suiting into the bin
matchFirst <- 1
while( !is.na(matchFirst) ){
i <- toBin[matchFirst]
dfCntBin$bin[i] <- binNr
toBin <- toBin[-matchFirst]
binCnt <- binCnt + dfCntBin$cnt[i]
freeCnt <- maxBinSize - binCnt
matchFirst <- if(freeCnt==0) NA else {
which( dfCntBin$cnt[toBin] <= freeCnt)[1]}
}
}
#
dfCntBin$id <- rownames(dfCntBin)
xBin <- merge(x, dfCntBin)
##value<< a list of subsets of the data frame
split(x, xBin$bin)
}
splitDfId(x, x$id)
splitDfId(x, x$id, 6)
splitDfId(x, x$id, 3)
如果性能是一个问题,那么搜索第一个仍然匹配的子集:which(dfCntBin$cnt[toBin] <= freeCnt)[1]
仍然可以是speeded up .
关于r - 如何通过保持 id 的完整性将 df 分成更小的部分,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28267382/