如何将大型数据框拆分为约的较小部分。相等的长度使得一些具有相同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&#39; s列表),以便id
保持不变?
所需的输出:here we split x into approx. 3 equal parts
[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
编辑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
分散在每个部分上。
答案 0 :(得分:1)
我假设您估计每个子集中的预期行数,即bin。
以下代码开始填充垃圾箱,从最大的id-subsets开始。然后连续地将仍然适合的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。