我有一个分组数据集,我想重新校准以提供更多的分析数据点。基本上,我想将每组中最小数字(负数)的正数等值添加到该组中的所有数字。请注意,我只希望此规则适用于仅包含负数的组。例如,在下面的数据框A中,规则不需要应用于A1,因为它不包含任何负数。
以下是一个示例数据框:
x_1 <- c("A1", "A1","A1", "B10", "B10", "B10","B10", "B500", "C100", "C100", "C100",
"D40", "G100", "G100")
z_1 <- c(1.1, 1.4, 1.6, -1.0, -2.2, 3, 2.3, 2.0, -3.4, -4.1, 2, 2, 2.4, -3.5)
A <- data.frame(x_1, z_1)
x_1 z_1
A1 1.1
A1 1.4
A1 1.6
B10 -1.0
B10 -2.2
B10 3.0
B10 2.3
B500 2.0
C100 -3.4
C100 -4.1
C100 2.0
D40 2.0
G100 2.4
G100 -3.5
我想要实现的结果由下面的数据框B给出:
b_2 <- c(1.1, 1.4, 1.6, 0, 1.2, 4.5, 5.2, 2.0, 0, 0.7, 6.1, 2.0, 0, 5.9)
B <- data.frame(x_1, b_2)
x_1 b_2
A1 1.1
A1 1.4
A1 1.6
B10 0.0
B10 1.2
B10 4.5
B10 5.2
B500 2.0
C100 0.0
C100 0.7
C100 6.1
D40 2.0
G100 0.0
G100 5.9
例如,为了获得b_2[4:7]
,我将2.2添加到所有其他数字等等。
我已经开始使用G <- A[order(A$x_1, A$z_1), ]
对数据进行排序,但我不知道可以用来执行此任务的任何其他功能。匹配函数在这里没有多大用处。
我做了一个简短的搜索,但我仍然不知道还有什么可以在这里使用。因此,我热烈欢迎任何有用的建议。
答案 0 :(得分:2)
如果我正确理解您的问题,则无需先order
您的数据。只需在ave
中使用min
和within
:
within(A, {
Mods <- ave(z_1, x_1, FUN = min)
Mods[Mods > 0] <- 0
Mods <- abs(Mods)
z_2 <- z_1 + Mods
rm(Mods)
})
# x_1 z_1 z_2
# 1 A1 1.1 1.1
# 2 A1 1.4 1.4
# 3 A1 1.6 1.6
# 4 B10 -1.0 1.2
# 5 B10 -2.2 0.0
# 6 B10 3.0 5.2
# 7 B10 2.3 4.5
# 8 B500 2.0 2.0
# 9 C100 -3.4 0.7
# 10 C100 -4.1 0.0
# 11 C100 2.0 6.1
# 12 D40 2.0 2.0
# 13 G100 2.4 5.9
# 14 G100 -3.5 0.0
更直接的方法(慷慨借用@ BrodieG的答案)是将within
内容更改为更直接的方法:
with(A, z_1 - ave(z_1, x_1, FUN = function(x) min(0, min(x))))
答案 1 :(得分:2)
这是一个data.table解决方案:
library(data.table)
data.table(A)[, list(z_1, z_1a=z_1 - min(0, z_1)), by=x_1]
# x_1 z_1 z_1a
# 1: A1 1.1 1.1
# 2: A1 1.4 1.4
# 3: A1 1.6 1.6
# 4: B10 -1.0 1.2
# 5: B10 -2.2 0.0
# 6: B10 3.0 5.2
# 7: B10 2.3 4.5
# 8: B500 2.0 2.0
# 9: C100 -3.4 0.7
# 10: C100 -4.1 0.0
# 11: C100 2.0 6.1
# 12: D40 2.0 2.0
# 13: G100 2.4 5.9
# 14: G100 -3.5 0.0