Easiest way to subtract associated with one factor

2020-02-13 04:28发布

I've got a dataframe containing rates for 'live' treatments and rates for 'killed' treatments. I'd like to subtract the killed treatments from the live ones:

df <- data.frame(id1=gl(2, 3, labels=c("a", "b")),
                 id2=rep(gl(3, 1, labels=c("live1", "live2", "killed")), 2), 
                 y=c(10, 10, 1, 12, 12, 2),
                 otherFactor = gl(3, 2))

I'd like to subtract the values of y for which id2=="killed" from all the other values of y, separated by the levels of id1, while preserving otherFactor. I would end up with

id1    id2   y otherFactor
  a  live1   9           1
  a  live2   9           1
  b  live1  10           2
  b  live2  10           3

This almost works:

df_minusKill <- ddply(df, .(id1), function(x) x$y[x$id2!="killed"] - x$y[x$id2=="killed"])
names(df_minusKill) <- c("id1", "live1", "live2")
df_minusKill_melt <- melt(df_minusKill, measure.var=c("live1", "live2"))

except that you lose the values of otherFactor. Maybe I could use merge to put the values of otherFactor back in, but in reality I have about a dozen "otherFactor" columns, so it would be less cumbersome to just keep them in there automatically.

标签: r plyr
2条回答
Melony?
2楼-- · 2020-02-13 05:06

The by function can process sections of dataframe separately by factors (or you could use lapply(split(df , ...)):

>  by(df, df$id1, FUN= function(x) x[['y']]-x[ x$id2=="killed", "y"] )
df$id1: a
[1] 9 9 0
--------------------------------------------------------------------------- 
df$id1: b
[1] 10 10  0
> unlist( by(df, df$id1, FUN= function(x) x[['y']]-x[ x$id2=="killed", "y"] ) )
a1 a2 a3 b1 b2 b3 
 9  9  0 10 10  0 

You could assign this to a column in df and subset out the rows with id2 not equal to 'killing'.

查看更多
聊天终结者
3楼-- · 2020-02-13 05:23
df2 <- ddply(df, .(id1), transform, y = y-y[id2=="killed"])
df2[-which(df2$id2=="killed"),]
  id1   id2  y otherFactor
1   a live1  9           1
2   a live2  9           1
4   b live1 10           2
5   b live2 10           3
查看更多
登录 后发表回答