Скажем, у меня есть следующий фрейм данных:
A B C
1 15 14 12
2 7 1 6
3 8 22 5
4 11 5 1
5 4 12 4
Я хочу вычислить разницу между строками, а затем разделить разницу на значение предыдущей строки. Это делается для каждой переменной.
Результат будет примерно таким:
A B C A_r B_r C_r
1 15 14 12 NA NA NA
2 7 1 6 -0.53 -0.93 -0.50
3 8 22 5 0.14 21 -0.16
4 11 5 1 ... ... ...
5 4 12 4 ... ... ...
Общая формула будет такой:
R (n) = [S (n) - S (n-1)] / S (n-1)
Где R представляет вновь вычисляемую переменную, а S представляет текущую переменную, для которой вычисляется значение R (в этом примере A, B, C).
Я знаю, что могу использовать функцию diff для вычисления разницы, но я не знаю, как разделить эту разницу на значения предыдущих строк.





Мы можем использовать across с lag - зациклить across все столбцы (everything()), применить формулу и создать новые столбцы, изменив .names, то есть добавив суффикс _r с соответствующими именами столбцов ({.col})
library(dplyr)
df1 <- df1 %>%
mutate(across(everything(), ~ (. - lag(.))/lag(.),
.names = "{.col}_r"))
-выход
df1
A B C A_r B_r C_r
1 15 14 12 NA NA NA
2 7 1 6 -0.5333333 -0.9285714 -0.5000000
3 8 22 5 0.1428571 21.0000000 -0.1666667
4 11 5 1 0.3750000 -0.7727273 -0.8000000
5 4 12 4 -0.6363636 1.4000000 3.0000000
Или используйте base R с diff
df1[paste0(names(df1), "_r")] <- rbind(NA,
diff(as.matrix(df1)))/rbind(NA, df1[-nrow(df1),])
@акрун. Как мы могли бы применить across2 здесь: Для первого шага: df %>% mutate(across2(everything(), -last_col(), -)) выдает ошибку.
@Jamess11 across зацикливается на столбцах, ~ — это компактный способ указания лямбда-функции, т. е. function(x) .. .. lag дает отставание столбца, т. е. v1 <- 1:5; lag(v1)
@TarJae Ваш синтаксис как бы зацикливается на двух блоках наборов данных, то есть один со всеми столбцами, а второй без последнего столбца. между соседними элементами внутри столбца, а не между соседними столбцами
О, сейчас проверил. Я думал, что ОП хочет разницу между столбцами, поэтому BA, CB, речь идет о разнице строк. Спасибо мастер.
@TarJae Кроме того, поскольку формула применяется внутри столбца, across2 может быть не очень хорошим вариантом (иначе вам, возможно, придется перенести набор данных)
Спасибо за быстрый ответ! Итак, если я правильно понял,
~ (. - lag(.))/lag(.)означает применить эту формулу ко всем строкам (~), где каждая строка представлена точкой (.), а отставание представляет предыдущую строку?