如果至少有一个值为零,我想计算行的abs(差异)(当前行的当前行)。如果两个值都是非零值,则应返回0.
示例:列'A'显示初始数据,'Diff'显示我想要的内容:
df <- data.frame(A=c(0,0,1,2,3,4,0,0),Diff=c(0,0,1,0,0,0,4,0))
由于
答案 0 :(得分:0)
以下是使用 dplyr
包和lag
函数的方法:
library(dplyr)
df1 <- data.frame(A=c(0,0,1,2,3,4,0,0),Diff=c(0,0,1,0,0,0,4,0))
df1 %>%
mutate(lag_A = lag(A),
Diff2 = abs(A - lag_A)) %>%
mutate(Diff2 = ifelse(is.na(lag_A), 0,
ifelse(A == 0 | lag_A == 0, Diff2, 0)))
A Diff lag_A Diff2
1 0 0 NA 0
2 0 0 0 0
3 1 1 0 1
4 2 0 1 0
5 3 0 2 0
6 4 0 3 0
7 0 4 4 4
8 0 0 0 0
然后,您可以使用select
函数来获取所需的列。我离开了表格中的所有列来说明解决方案。
答案 1 :(得分:0)
我会假设Diff的第一个值不是你想要的操作的结果,因为A的第一个值没有前面的值,所以我选择在答案上重复它,但您可以添加任何内容而不是A[1]
。
编辑:我还假设你想要一个仅使用base的解决方案,否则,bouncyball的解决方案就像魅力一样。
Diff = rep(0,(length(A)-1))
Diff[which(mapply(xor,A[-1],A[-length(A)]))] = abs(A[-1][which(mapply(xor,A[-1],A[-length(A)]))]-A[-length(A)][which(mapply(xor,A[-1],A[-length(A)]))])
Diff = c(A[1],Diff)
你可以通过使它成为这样的命名函数来改进:
foo = function(A){
Diff = rep(0,(length(A)-1))
Diff[which(mapply(xor,A[-1],A[-length(A)]))] = abs(A[-1][which(mapply(xor,A[-1],A[-length(A)]))]-A[-length(A)][which(mapply(xor,A[-1],A[-length(A)]))])
Diff = c(A[1],Diff)
Diff
}
我们使用以下代码而不是操作A:
A[-1]
,产生0 1 2 3 4 0 0
(等于A但没有第一个元素)
和A[-length(A)]
,产生:0 0 1 2 3 4 0
(等于A,但没有最后一个元素)。
如果我们从后者中减去第一个,我们将元素减法正确,但我们仍然需要知道 这些减法需要发生。
通过组合函数xor,mapply和which(所有这些都是基础成员),如下所示:
which(mapply(xor,A[-1],A[-length(A)]))
我们发现:
2 6
这是A [-1]和A [-length(A)]中的位置的索引,其中应该进行减法。
现在我们使用:
创建一个名为Diff的0向量与我们的新向量大小相同 Diff = rep(0,length(A)-1)
,然后我们使用:
Diff[which(mapply(xor,A[-1],A[-length(A)]))] = abs(A[-1][which(mapply(xor,A[-1],A[-length(A)]))]-A[-length(A)][which(mapply(xor,A[-1],A[-length(A)]))])
最后我们使用Diff = c(A[1],Diff)
再次放回第一个元素。