如何计算一列中值之间的成对差异?
计算应该从前两个值开始,并且应该继续使用接下来的两个值,就像在“desired_result”列中一样:
data <- data.frame(data = c(5, NA, NA, NA, 3, NA, NA, 4, NA, 3, NA, NA, NA, 6, 1, 4, NA, 2))
答案 0 :(得分:4)
这是一个单行:
data$desired_result[which(!is.na(data$data))[c(FALSE, TRUE)]] <-
rev(diff(rev(na.omit(data$data))))[c(TRUE, FALSE)]
其中which(!is.na(data$data))
查找data$data
的非NA条目,然后添加c(FALSE, TRUE)
仅选择每秒一个。另外,na.omit(data$data)
会丢弃NA值,rev
会反转此向量,diff
会带来差异,rev
会将向量反转回正确的顺序,最后,因为我们没有&# 39;我想要所有的差异,我再次用c(TRUE, FALSE)
选择每一秒。
答案 1 :(得分:3)
与朱利叶斯相同,但更短更快:
data$desired_result[which(!is.na(data$data))[c(FALSE, TRUE)]] <-
diff(na.omit(data$data))[c(TRUE, FALSE)] * -1
由于diff()
计算x1 - x0
,rev()
可以替换为diff() * -1
使用microbenchmark进行速度比较:
Unit: microseconds
expr min lq mean median uq max neval cld
julius 38.096 43.757 51.44687 46.143 50.8655 170511.851 1e+05 b
this 32.828 37.501 43.02233 39.548 43.4390 7405.489 1e+05 a
答案 2 :(得分:1)
如果您希望得到与您描述的结果完全 here 你可以使用:
> data <- data.frame(data = c(5, NA, NA, NA, 3, NA, NA, 4, NA, 3, NA,
> NA, NA, 6, 1, 4, NA, 2)) %>% mutate(index = 1:n())
>
> ex = data %>% filter(!is.na(data))
>
> df2 = data.frame(index = rollapply(ex$index, width = 2, by = 2, last),
> desired_results = rollapply(ex$data, width = 2, by = 2, FUN = function (x) -1*diff(x)))
>
> data2 = left_join(data, df2, by = "index") %>% select(-index)
data desired_results
1 5 NA
2 NA NA
3 NA NA
4 NA NA
5 3 2
6 NA NA
7 NA NA
8 4 NA
9 NA NA
10 3 1
11 NA NA
12 NA NA
13 NA NA
14 6 NA
15 1 5
16 4 NA
17 NA NA
18 2 2
但如果您只是想要差异,那么您可以使用:
rollapply(na.omit(data$data), by = 2, width = 2, diff)
要注意你会得到负面结果:-2 -1 -5 -2