在列

时间:2017-06-30 09:09:23

标签: r dataframe split

我有一个数据框

df<-data.frame(var1=c(1:11),I_var1=c(11:21),
               var2=c(rep(c(0,0.1),each=5),0.1),var4=c(rep(c(0:4),2),4))

var1 I_var1 var2 var4
  1     11  0.0    0
  2     12  0.0    1
  3     13  0.0    2
  4     14  0.0    3
  5     15  0.0    4
  6     16  0.1    0
  7     17  0.1    1
  8     18  0.1    2
  9     19  0.1    3
 10     20  0.1    4
 11     21  0.1    4

我必须在特定数字的每个重复单元处拆分,即df $ var4 == 4

我试过了 -

X <- split(df,cut(df$var4,4))

但这是错误的结果。 我想要的是 - 2个数据帧(或列表作为拆分列表),其中var4介于0和4之间。第二个数据框应该包含var4 == 4的两行。

我不想使用子集,因为原始数据帧具有> 10Mil记录。

我如何做得非常快?

4 个答案:

答案 0 :(得分:3)

简单地:

split(df,duplicated(df$var4))

$`FALSE`
  var1 I_var1 var2 var4
1    1     11    0    0
2    2     12    0    1
3    3     13    0    2
4    4     14    0    3
5    5     15    0    4

$`TRUE`
   var1 I_var1 var2 var4
6     6     16  0.1    0
7     7     17  0.1    1
8     8     18  0.1    2
9     9     19  0.1    3
10   10     20  0.1    4
11   11     21  0.1    4

答案 1 :(得分:1)

library(data.table)
library(dplyr)

df<-data.frame(var1=c(1:11),I_var1=c(11:21),
               var2=c(rep(c(0,0.1),each=5),0.1),var4=c(rep(c(0:4),2),4))

cuts <- which(df$var4==0)
cuts <- c(cuts,nrow(df))
df <- as.data.table(df)
df[,nrow:=.I]
intervals <- list()
for(i in 1:(length(cuts)-1)){ # i <- 1
  intervals[[i]] <- seq(cuts[i],cuts[i+1]-1,1) 
}
intervals[[i]] <- c(intervals[[i]],max(intervals[[i]])+1)


list <- list()
for(i in 1:length(intervals)){ # i <- 1
  list[[i]] <- df[nrow%in%intervals[[i]],]
}

作为输出

> list
[[1]]
   var1 I_var1 var2 var4 nrow
1:    1     11    0    0    1
2:    2     12    0    1    2
3:    3     13    0    2    3
4:    4     14    0    3    4
5:    5     15    0    4    5

[[2]]
   var1 I_var1 var2 var4 nrow
1:    6     16  0.1    0    6
2:    7     17  0.1    1    7
3:    8     18  0.1    2    8
4:    9     19  0.1    3    9
5:   10     20  0.1    4   10
6:   11     21  0.1    4   11

<强>更新

或更短

library(data.table)
library(dplyr)

df<-data.frame(var1=c(1:11),I_var1=c(11:21),
               var2=c(rep(c(0,0.1),each=5),0.1),var4=c(rep(c(0:4),2),4))

cuts <- which(df$var4==0)
df <- as.data.table(df)
df[,nrow:=.I]
list <- list()
for(i in 1:length(cuts)){ # i <- 2
 if(i==length(cuts)){
   list[[i]] <- df[nrow%in%c(cuts[i]:nrow(df)),]
 }else{
   list[[i]] <- df[nrow%in%c(cuts[i]:(cuts[i+1]-1)),]
 } 
}

答案 2 :(得分:0)

(不确定,如果我完全理解你的话......)

df<-data.frame(var1=c(1:11),I_var1=c(11:21),
               var2=c(rep(c(0,0.1),each=5),0.1),var4=c(rep(c(0:4),2),4))

df$lagvar4<-c(0,df$var4[-length(df$var4)])
split(df[!(colnames(df) %in% c("var4","lagvar4"))],cumsum(df$lagvar4==4))

答案 3 :(得分:0)

以下是dplyr解决方案:

df <- data.frame(var1=c(1:11),I_var1=c(11:21),
           var2=c(rep(c(0,0.1),each=5),0.1),var4=c(rep(c(0:4),2),4))

df %>% 
  group_by(var4) %>% 
  mutate(split = row_number()) %>% 
  split(., f = .$split)