根据R中的列将数据帧分成两半

时间:2018-08-16 15:59:10

标签: r sorting dataframe split

我需要将数据帧拆分成两半,但不能拆分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万行。我怎么也可以优化呢?

2 个答案:

答案 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并使用<作为分裂因子的最简单方法。