【问题标题】:split dataframe at each repeating point in a column在列中的每个重复点拆分数据框
【发布时间】:2017-06-30 09:09:22
【问题描述】:

我有一个数据框

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。

我不想使用子集,因为原始数据帧有 >1000 万条记录。

我如何做到这一点并且速度非常快?

【问题讨论】:

  • 它应该是什么样子?
  • 2 个包含所有列的列表,但 var4 应该是 0:4,因为我想在每次 var4 列中出现 4 时剪切

标签: r dataframe split


【解决方案1】:

简单地说:

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

【讨论】:

    【解决方案2】:

    这个

    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)),]
     } 
    }
    

    【讨论】:

      【解决方案3】:

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

      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))
      

      【讨论】:

      • @P Lapointe 谢谢!!我不知道这个重复的功能!真的很有帮助。
      【解决方案4】:

      这是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)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-10-27
        • 1970-01-01
        • 1970-01-01
        • 2019-09-17
        • 2020-05-05
        • 1970-01-01
        相关资源
        最近更新 更多