在R中校准数据

时间:2014-02-04 17:46:20

标签: r dataframe

我有一个分组数据集,我想重新校准以提供更多的分析数据点。基本上,我想将每组中最小数字(负数)的正数等值添加到该组中的所有数字。请注意,我只希望此规则适用于仅包含负数的组。例如,在下面的数据框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), ]对数据进行排序,但我不知道可以用来执行此任务的任何其他功能。匹配函数在这里没有多大用处。

我做了一个简短的搜索,但我仍然不知道还有什么可以在这里使用。因此,我热烈欢迎任何有用的建议。

2 个答案:

答案 0 :(得分:2)

如果我正确理解您的问题,则无需先order您的数据。只需在ave中使用minwithin

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