Jak mogę obliczyć różnicę parę między wartościami w jednej kolumnie?

Obliczenia powinno rozpocząć się od dwóch pierwszych wartości i powinny być kontynuowane z następnymi dwoma wartościami, ponieważ odbywa się w kolumnie "Rodzina_Result" tutaj:

here

data <- data.frame(data = c(5, NA, NA, NA, 3, NA, NA, 4, NA, 3, NA, NA, NA, 6, 1, 4, NA, 2))
r
3
flobrr 19 luty 2018, 20:19

3 odpowiedzi

Najlepsza odpowiedź

Jeśli chcesz mieć wynik dokładnie , jak opisałeś Tutaj . możesz użyć:

> 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

Ale jeśli po prostu chcesz różnicę, możesz użyć:

rollapply(na.omit(data$data), by = 2, width = 2, diff)

Uważaj, że otrzymasz negatywne wyniki: -2 -1 -5 -2

1
Leonardo Siqueira 19 luty 2018, 17:53

Oto jednoskładnikowa:

data$desired_result[which(!is.na(data$data))[c(FALSE, TRUE)]] <- 
  rev(diff(rev(na.omit(data$data))))[c(TRUE, FALSE)]

Gdzie which(!is.na(data$data)) znajduje wpisy non-NA data$data, a następnie dodanie c(FALSE, TRUE) wybiera tylko co sekundę. Również na.omit(data$data) odrzuca wartości na, rev odwraca ten wektor, diff zajmuje różnice, rev odwraca wektor z powrotem do właściwej kolejności, a na koniec, ponieważ my, odkąd nie T chcę wszystkie różnice, ponownie wybiorę co sekundę z c(TRUE, FALSE).

4
Julius Vainora 19 luty 2018, 17:51

Tak samo jak Julius, ale nawet krótszy i szybszy:

data$desired_result[which(!is.na(data$data))[c(FALSE, TRUE)]] <- 
  diff(na.omit(data$data))[c(TRUE, FALSE)] * -1

Ponieważ diff() oblicza x1 - x0, zarówno rev() można zastąpić przez diff() * -1

Porównanie prędkości za pomocą 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
3
Aleh 19 luty 2018, 23:19