我需要将数据帧拆分成两半,但不能拆分ID。假设我有这些数据
x <- expand.grid("id"=c("a","b","c"), c(1:2),c(1:2))
row.names(x) <- NULL
x <- x[order(x$id),]
> x
id Var2 Var3
a 1 1
a 2 1
a 1 2
a 2 2
b 1 1
b 2 1
b 1 2
b 2 2
c 1 1
c 2 1
c 1 2
c 2 2
如果我在中间拆分,则每个数据帧中的id =“ b”。我需要确保当我分成2个时,必须经过上半部分的最后一个id。
> df.1
id Var2 Var3
a 1 1
a 2 1
a 1 2
a 2 2
b 1 1
b 2 1
b 1 2
b 2 2
> df.2
id Var2 Var3
c 1 1
c 2 1
c 1 2
c 2 2
PS:我的真实数据有8000万行。我怎么也可以优化呢?
答案 0 :(得分:0)
带有data.table:
library(data.table)
setDT(x)
x[ , groupid := rleid(id)]
split(x, x$groupid > x[nrow(x)/2,groupid])
答案 1 :(得分:0)
您可以使用此:
listOfTwoDF <- split(x, rank(x$id, ties.method='max') >= nrow(x)/2)
# > listOfTwoDF
# $`FALSE`
# id Var2 Var3
# 1 a 1 1
# 4 a 2 1
# 7 a 1 2
# 10 a 2 2
#
# $`TRUE`
# id Var2 Var3
# 2 b 1 1
# 5 b 2 1
# 8 b 1 2
# 11 b 2 2
# 3 c 1 1
# 6 c 2 1
# 9 c 1 2
# 12 c 2 2
# if you prefer two variables :
df.1 <- listOfTwoDF[[1]]
df.2 <- listOfTwoDF[[2]]
说明:
向量的每个元素的 rank
函数返回该元素在有序向量中的排名。因此,例如,给定向量v=c(7,8,10,5)
返回c(2,3,4,1)
,因为7
在排序后的v
中将排在第二个位置,8
将是第三个位置,{ {1}}将排在第四位,10
将排在第一位。
如果是平局,则可以选择算法将值分配给具有相同值的所有元素,然后通过选择5
来分配组的最大排名,例如:
max
因此,您可能会注意到,返回的值基本上是每个组的行数的累积值,其中该累积值在组的每个元素上重复。
话虽这么说,我们可以在rank(c('c','b','b','b','a','e','e','d'),ties.method='max') --> c(5, 4, 4, 4, 1, 8, 8, 6)
上将其与ties.method ='max'一起使用,并将id
比>=
的排名与{{1 }}。
使用功能nrows(x)/2
并使用<
作为分裂因子的最简单方法。