根据id将数据帧拆分为列表

时间:2015-02-11 19:31:43

标签: r

请注意,我不是交易程序员。我是文学专业的学生。所以请耐心等待。

我想改进现有的工作程序。当然函数split是一个选项(但我不确定如何)。

基本上,我正在尝试将现有数据框细分为子样本列表,以便id的序列不会被分割成第二个列表。

以下是工作示例和示例数据:

 df <- data.frame(id=c(rep(1,3),rep(2,2),rep(3,3),rep(4,2),5,6,7,8,9,rep(10,5)),r1=rep(1,40),r2=rep(2,40))


x <- transform(df, rec=ave(df$id,df$id, FUN=seq_along))
x$cum <- cumsum(x$rec)
x$dif <- diff(c(0,x$cum),1)
x$lab <- ifelse(x$dif!=1,0,1)
x$seq <- seq_along(x$id)
x$subs <- x$lab*x$seq 

seqrow <- seq(1,nrow(x),3) # how many rows approx. per part
rw <- x$subs[x$subs %in% seqrow]

start_rw <- c(1,rw[2:length(rw)])
end_rw <- c(start_rw[2:length(start_rw)]-1,nrow(x))

df.lst <- list()
  for(i in 1:length(start_rw)){
     df.lst[[i]] <- x[(start_rw[i]:end_rw[i]), ]
}

在每个列表中,id也应该越来越多地排序,并且应该根据id进行排列。

1 个答案:

答案 0 :(得分:2)

阅读您的代码,我会将您的程序概括为:

  1. 计算seqrow,这是您愿意拆分列表的行号
  2. 仅在df seqrow所在的位置df$id拆分start_rw(上面没有出现);此职位列表在您的代码中称为duplicated
  3. 您可以使用df$id来确定start_rw是否出现在上方,这样您就可以更轻松地抓取seqrow <- seq(1,nrow(df),3) (start_rw <- intersect(which(!duplicated(df$id)), seqrow)) # [1] 1 4 13 16

    df

    剩下的就是将diff分成这些位置。您可以使用(groups <- rep(seq(start_rw), times=diff(c(start_rw, nrow(df)+1)))) # [1] 1 1 1 2 2 2 2 2 2 2 2 2 3 3 3 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 df.lst2 <- split(df, groups) 计算每个分组中的元素数量:

    all.equal(unname(df.lst2), lapply(df.lst, function(x) x[,1:3]))
    # [1] TRUE
    

    这匹配代码的输出:

    {{1}}