繁体   English   中英

合并data.frame中的行

[英]Combining rows in a data.frame

我有一个data.frame ,看起来像下面的示例data.frame

df = data.frame(id = c("a","b","c","d","e","f","g"), start = c(10,20,30,40,50,60,70), end = c(15,25,35,45,55,65,75), flag = c(0,1,1,0,1,0,1))
> df
  id start end flag
1  a    10  15    0
2  b    20  25    1
3  c    30  35    1
4  d    40  45    0
5  e    50  55    1
6  f    60  65    0
7  g    70  75    1

df$start升序排序,然后按df$end升序排序。 我正在寻找一个函数,该函数将合并df$flag == 1所有行,而不合并df$flag == 0 合并的行的df$id应该用逗号分隔符连接起来,它们的df$start应该是具有min df$start的行,而df$end应该是具有max df$end 最后,对于他们, df$flag应该为1。

因此,对于此示例,返回的data.frame应该为:

res.df = data.frame(id = c("a","b,c","d","e","f","g"), start = c(10,20,40,50,60,70), end = c(15,35,45,55,65,75), flag = c(0,1,0,1,0,1))
> res.df
   id start end flag
1   a    10  15    0
2 b,c    20  35    1
3   d    40  45    0
4   e    50  55    1
5   f    60  65    0
6   g    70  75    1

对于aggregate ,很难做到这一点,因为将相同的功能依次应用于每个列。 多次调用aggregate可以分段完成此任务,然后将其合并。 但是, data.table在同一调用中允许使用不同的聚合函数:

library(data.table)
d <- data.table(df)

d[,list(id=paste(id, collapse=','), start=min(start), end=max(end)), 
  by=list(flag, cumsum(flag==0))
]
   flag cumsum  id start end
1:    0      1   a    10  15
2:    1      1 b,c    20  35
3:    0      2   d    40  45
4:    1      2   e    50  55
5:    0      3   f    60  65
6:    1      3   g    70  75

您最终会得到一个新列,如果需要,可以将其删除。 上的条件cumsum(flag==0)防止任何行与flag==0从骨料被组合,并且保持该非连续flag==1值在结果中分离。

这是使用aggregatemerge base解决方案:

merge(merge(aggregate(start ~ flag + cumsum(flag==0), data=df, FUN=min), 
           aggregate(end ~ flag + cumsum(flag==0), data=df, FUN=max)
      ), 
     aggregate(id ~ flag + cumsum(flag==0), data=df, FUN=paste, sep=',')
)
  flag cumsum(flag == 0) start end   id
1    0                 1    10  15    a
2    0                 2    40  45    d
3    0                 3    60  65    f
4    1                 1    20  35 b, c
5    1                 2    50  55    e
6    1                 3    70  75    g

如果使用Reduce和数据帧列表进行合并,则代码更具可读性:

Reduce(merge, list(aggregate(start ~ flag + cumsum(flag==0), data=df, FUN=min), 
                   aggregate(end   ~ flag + cumsum(flag==0), data=df, FUN=max),
                   aggregate(id    ~ flag + cumsum(flag==0), data=df, FUN=paste, sep=',')
              )
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM