-1

我有一个如下所示的数据集:

groups <- c(1:20)
A <- c(1,3,2,4,2,5,1,6,2,7,3,5,2,6,3,5,1,5,3,4)
B <- c(3,2,4,1,5,2,4,1,3,2,6,1,4,2,5,3,7,1,4,2)
position <- c(2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1)
sample.data <- data.frame(groups,A,B,position)
head(sample.data)
      groups     A       B     position
  1      1       1       3        2
  2      2       3       2        1
  3      3       2       4        2
  4      4       4       1        1
  5      5       2       5        2
  6      6       5       2        1

“位置”列总是在 2 和 1 之间交替。我想在 R 中进行此计算:从第一行开始,如果它在位置 1,请忽略它。如果它从 2 开始(如本例所示),则计算如下:

  • 取 A 列中位于位置 2 的前 2 个值,将它们平均,然后减去位于位置 1 的第一个值(在本例中:(1+2)/2 - 3 = -1.5)。然后对下一组值重复计算,使用最后一个位置 2 值作为起点,即下一个计算将是 (2+2)/2 - 4 = -2。
  • 所以基本上,在这个例子中,计算是针对这些组的值进行的:1-2-3、3-4-5、5-6-7 等(前一个的最后一个值是第一个下一组计算的值)
  • 重复计算直到结束。也对 B 列执行相同的操作。
  • 由于我需要完整的原始数据框,因此将新计算的值放入一个新的数据框中,其中 dA 和 dB 列分别对应于 A 列和 B 列的计算值(如果不可能,则可以将它们创建为分离的数据帧,然后我会将它们提取到一个中)。

所需的输出(来自示例):

    dA    dB
1  -1.5  1.5
2   -2   3.5
3  -3.5  2.5
4  -4.5  2.5
5  -4.5  2.5
6  -2.5   4
4

2 回答 2

1

由于您的值position始终在 1 和 2 之间交替,您可以定义奇数行i1的索引和偶数行的索引i2,并进行计算:

## In case first row has position==1, we add an increment of 1 to the indexes
inc=0
if(sample.data$position[1]==1)
{inc=1}
i1=seq(1+inc,nrow(sample.data),by=2)
i2=seq(2+inc,nrow(sample.data),by=2)
res=data.frame(dA=(lead(sample.data$A[i1])+sample.data$A[i1])/2-sample.data$A[i2],
dB=(lead(sample.data$B[i1])+sample.data$B[i1])/2-sample.data$B[i2]);

这将返回:

dA  dB
1  -1.5 1.5
2  -2.0 3.5
3  -3.5 2.5
4  -4.5 2.5
5  -4.5 2.5
6  -2.5 4.0
7  -3.5 2.5
8  -3.0 3.0
9  -3.0 4.5
10   NA  NA

最后一行返回 NA,如果需要,您可以将其删除。

res=na.omit(res)
于 2017-05-15T21:16:51.843 回答
1
groups <- c(1:20)
A <- c(1,3,2,4,2,5,1,6,2,7,3,5,2,6,3,5,1,5,3,4)
B <- c(3,2,4,1,5,2,4,1,3,2,6,1,4,2,5,3,7,1,4,2)
position <- c(2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1)
sample.data <- data.frame(groups,A,B,position)

start <- match(2, sample.data$position)
twos <- seq(from = start, to = nrow(sample.data), by = 2)

df <- 
  sapply(c("A", "B"), function(l) {
    sapply(twos, function(i) { 
      mean(sample.data[c(i, i+2), l]) - sample.data[i+1, l]
    })
  })

df <- setNames(as.data.frame(df), c('dA', 'dB'))
于 2017-05-15T22:54:24.477 回答