Reputation: 53
I want to aggregate rows in my table under certain conditions. For example I have :
x <- data.frame("id"=c("T","T","R","R"),"value"=c(10,-5,10,-5),"level"=c(3,2,1,2))
print(x)
My condition is : for the same "id" if the level of a negative value is lower than the level of the positive value, then I can aggregate through summing values. So I get :
x <- data.frame("id"=c("T","R","R"),"value"=c(5,10,-5))
print(x)
Can I do this using aggregate() fucntion ?
Upvotes: 1
Views: 59
Reputation: 5456
Or:
x <- data.frame("id"=c("T","T","R","R"),"value"=c(10,-5,10,-5),"level"=c(3,2,1,2))
lookup_vec <- setNames(x[sign(x$value) == 1, ]$level,
as.character(x[sign(x$value) == 1, ]$id))
x$level_plus <- lookup_vec[as.character(x$id)]
x$level_plus <- ifelse(x$level_plus >= x$level, x$level_plus, x$level)
aggregate(value ~ id + level_plus, x, sum)[c("id", "value")]
# id value
# 1 R 10
# 2 R -5
# 3 T 5
Upvotes: 1
Reputation: 72593
You could use by
.
do.call(rbind, by(x, x$id, function(x) {i <- cbind(x, d=c(1, diff(x[, 3]))); i[i$d > 0, 1:2]}))
# id value
# 1 T 5
# 2 R 10
# 3 R -5
Upvotes: 0