合并R中的特定行

时间:2014-05-21 08:17:38

标签: r merge plyr

我想合并我的df的某些行的列值。例如,在以下df中,

  name time value
1   n1    1    10
2   n2    2    12
3    a    3     6
4    b    3    NA
5   n3    4     4

我想合并第3行和第3行。 4这样最终的df将是,

  name time value
1   n1    1    10
2   n2    2    12
3    a    3     6
5   n3    4     4

我的方法

在尝试了不同的方法后,我决定,

df1 <- ddply(df,
             .(time), #Split by time as events "a","b" will always same time
             function(y){
               if(all(y$name %in% c("a","b"))){ #Dont combine rows without "a"|"b"
                 y<-data.frame(t(apply(y, 2, min, na.rm=T))) #adply doesn't seem to work?
                 print(y) #Added here for debugging
                 }  
               y
               }
             )

print语句产生正确的答案,

  name time value
1    a    3     6

但输出df1是

  name time value
1   n1    1    10
2   n2    2    12
3    a    1     1
4   n3    4     4

我不知道1是怎么来的?

2 个答案:

答案 0 :(得分:1)

为什么不能使用duplicated删除重复的time值(行)?

> dat
#   name time value
# 1   n1    1    10
# 2   n2    2    12
# 3    a    3     6
# 4    b    3    NA
# 5   n3    4     4
> dat[!duplicated(dat$time), ]
#   name time value
# 1   n1    1    10
# 2   n2    2    12
# 3    a    3     6
# 5   n3    4     4

答案 1 :(得分:0)

问题是类型转换。在apply来电中,data.frame转换为matrix类型character。将其转换为data.frame时,character会转换为factor。然后在合并结果时,factor将转换为numeric。为避免转换为因素,您可以使用stringsAsFactors=FALSE,您的代码也可以使用。

df1 <- ddply(df,
             .(time), #Split by time as events "a","b" will always same time
             function(y){
               if(all(y$name %in% c("a","b"))){ #Dont combine rows without "a"|"b"
                 y<-data.frame(t(apply(y, 2, min, na.rm=T)), stringsAsFactors=FALSE) 
               }  
               y
             }
)

无论如何,这是一个替代解决方案,它更容易阅读,更不容易出错,而且可能更快。

require(data.table)
dt <- data.table(df)
dt[name %in% c("a","b"), `:=`(name=name[1], value=min(value, na.rm=TRUE)), by=time]
unique(dt)