从数据框的每个子集中减去第一个值。

3

我希望能够从数据框的每个子集中减去最小值,例如:

A <- c(1,3,5,6,4,5,6,7,10)
B <- rep(1:4, length.out=length(A))
df <- data.frame(A, B)
df <- df[order(B),]

进行减法操作将会得到:

  A B
1 0 1
2 3 1
3 9 1
4 0 2
5 2 2
6 0 3
7 1 3
8 0 4
9 1 4

第一列第四行(4,1)不应该是0吗?另外(7,1)也应该是0吧? - Arun
2个回答

6

我认为你展示的输出结果是不正确的。无论如何,根据你的解释,我认为这就是你想要的。这里使用了ave基础函数:

within(df, { A <- ave(A, B, FUN=function(x) x-min(x))})
  A B
1 0 1
5 3 1
9 9 1
2 0 2
6 2 2
3 0 3
7 1 3
4 0 4
8 1 4

当然还有其他替代方案,例如 plyrdata.table


哇,太快了,谢谢Arun,第一个出现。+1 是的,我的手算能力真的很差。 - Joe_P

3
回应Arun上面的评论,我认为你期望的输出可能有误。无论如何,您应该能够使用tapply计算子集,然后使用match将这些子集与原始值对齐:
subs <- tapply(df$A, df$B, min)

df$A <- df$A - subs[match(df$B, names(subs))]

df
  A B
1 0 1
5 3 1
9 9 1
2 0 2
6 2 2
3 0 3
7 1 3
4 0 4
8 1 4

1
(+1) 在这种情况下,您也可以直接执行以下操作:unlist(tapply(df$A, df$B, function(x) x - min(x)))(因为它们已经排序)。在大多数情况下,ave 更有用,因为它会按照相同的顺序输出结果。 - Arun
谢谢你们俩,对我来说真的很方便。毫无疑问,对我会有很多用处。 - Joe_P

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接