我想在R中创建一个数据集中的列,其中我从第1行减去第2行,从第3行减去第4行,依此类推。此外,我希望每行重复减法结果(例如,减法row2-row1的结果为-0.294803,我希望此值在row1和row2中都存在,因此对于减法的两个因子都重复两次,等等所有减法。)
这是我的数据集。
我尝试使用函数聚合但我没有成功。 任何提示?
答案 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)
一种方法是使用一个简单的循环:
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
如果您有大量数据,这种方法可能会很慢。并且通常R与另一种形式的迭代函数( apply 系列)更好地工作。
上面的相同代码可以像这样进行优化:
a$delta = rep(
sapply(seq(1, nrow(a), by=2 ),
function(i){ a[i+1,"log"] - a[i,"log"] }
),
each=2)
与第一个解决方案给出的结果完全相同,应该更快,但也更不直观。
最后,在我看来,考虑到您的数据类型,您尝试使用 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)), ]