我想合并我的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是怎么来的?
答案 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)