Как вычислить разницу между строками и разделить разницу на значение из предыдущей строки в R?

Скажем, у меня есть следующий фрейм данных:

    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 для вычисления разницы, но я не знаю, как разделить эту разницу на значения предыдущих строк.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
26
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мы можем использовать 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),])

Спасибо за быстрый ответ! Итак, если я правильно понял, ~ (. - lag(.))/lag(.) означает применить эту формулу ко всем строкам (~), где каждая строка представлена ​​​​точкой (.), а отставание представляет предыдущую строку?

Jamess11 09.05.2022 17:35

@акрун. Как мы могли бы применить across2 здесь: Для первого шага: df %>% mutate(across2(everything(), -last_col(), -)) выдает ошибку.

TarJae 09.05.2022 17:37

@Jamess11 across зацикливается на столбцах, ~ — это компактный способ указания лямбда-функции, т. е. function(x) .. .. lag дает отставание столбца, т. е. v1 <- 1:5; lag(v1)

akrun 09.05.2022 17:37

@TarJae Ваш синтаксис как бы зацикливается на двух блоках наборов данных, то есть один со всеми столбцами, а второй без последнего столбца. между соседними элементами внутри столбца, а не между соседними столбцами

akrun 09.05.2022 17:40

О, сейчас проверил. Я думал, что ОП хочет разницу между столбцами, поэтому BA, CB, речь идет о разнице строк. Спасибо мастер.

TarJae 09.05.2022 17:41

@TarJae Кроме того, поскольку формула применяется внутри столбца, across2 может быть не очень хорошим вариантом (иначе вам, возможно, придется перенести набор данных)

akrun 09.05.2022 17:42

Другие вопросы по теме