重复从第1行中减去第2行

时间:2016-07-05 11:44:19

标签: rstudio subtraction

我想在R中创建一个数据集中的列,其中我从第1行减去第2行,从第3行减去第4行,依此类推。此外,我希望每行重复减法结果(例如,减法row2-row1的结果为-0.294803,我希望此值在row1和row2中都存在,因此对于减法的两个因子都重复两次,等等所有减法。)

这是我的数据集。

enter image description here

我尝试使用函数聚合但我没有成功。 任何提示?

2 个答案:

答案 0 :(得分:1)

另一种可能的解决方案是:

x <- read.table("mydata.csv",header=T,sep=";")
x$diff <- rep(x$log[seq(2,nrow(x),by=2)] - x$log[seq(1,nrow(x),by=2)], each=2)

通过使用函数seq(),您可以生成行位置序列:

  

1,3,5,... 9

     

2,4,6,... 10

然后,代码将行2 ... 10减去行1 ... 9。使用命令rep()复制每个结果,并将其分配给新的列diff。

答案 1 :(得分:0)

解决方案1 ​​

一种方法是使用一个简单的循环:

download mydata.csv

a = read.table("mydata.csv",header=T,sep=";")
a$delta= NA
for(i in seq(1, nrow(a), by=2 )){
  a[i,"delta"] = a[i+1,"delta"] = a[i+1,"log"] - a[i,"log"]
}

这里发生的是for循环遍历每个奇数(这就是seq(...,by = 2)所做的。所以对于第一,第三,第五等行,我们分配给那个行和以下一个计算的差异。 返回:

> a
   su    match  log delta
1   1    match 5.80  0.30
2   1 mismatch 6.10  0.30
3   2    match 6.09 -0.04
4   2 mismatch 6.05 -0.04
5   3    match 6.42 -0.12
6   3 mismatch 6.30 -0.12
7   4    match 6.20 -0.20
8   4 mismatch 6.00 -0.20
9   5    match 5.90  0.19
10  5 mismatch 6.09  0.19

解决方案2

如果您有大量数据,这种方法可能会很慢。并且通常R与另一种形式的迭代函数( apply 系列)更好地工作。

上面的相同代码可以像这样进行优化:

a$delta = rep(
             sapply(seq(1, nrow(a), by=2 ),
                 function(i){ a[i+1,"log"] - a[i,"log"] }
             ),
          each=2)

与第一个解决方案给出的结果完全相同,应该更快,但也更不直观。

解决方案3

最后,在我看来,考虑到您的数据类型,您尝试使用 long 数据帧格式来使用复杂的方法。 我将其重新整形为 wide ,然后使用单独的列进行更逻辑的操作,而无需重复数据。

像这样:

a = read.table("mydata.csv",header=T,sep=";")
a = reshape(a, idvar = "su", timevar = "match", direction = "wide")
#now creating what you want became a very simple thing:
a$delta = a[[3]]-a[[2]]

返回:

>a
   su log.match log.mismatch delta
1  1      5.80         6.10  0.30
3  2      6.09         6.05 -0.04
5  3      6.42         6.30 -0.12
7  4      6.20         6.00 -0.20
9  5      5.90         6.09  0.19

增量列包含您需要的值。如果真的需要长格式进行进一步分析,您可以随时返回:

a= reshape(a, idvar = "su", timevar = "match", direction = "long")
#sort to original order:
a = a[with(a, order(su)), ]