Вычисление процентного изменения значений строки при переборе столбцов с использованием lapply в R - PullRequest
1 голос
/ 24 февраля 2020

У меня есть фрейм данных с недельными значениями для большого количества переменных. Я хочу перебрать каждый столбец и получить еженедельное изменение для каждой строки и переменной, выраженной в процентах.

Пример:

a = c(2,3,1,9)
b = c(4,5,8,1)
sentiment = cbind(a,b) %>% 
as.data.frame()`



Outcome should be: 
     a  b  a_delta  b_delta 
     2  4     NA      NA
     3  5     0.5     0.3
     1  8    -0.7     0.6
     9  1     8.0    -0.8

В моем текущем подходе я использую два шага: (1) создать еженедельную задержку, (2) вычислить разницу в процентах между задержанным значением и значением. Там нет сообщения об ошибке, но расчет по-прежнему неверен, и я не уверен, почему. Любая помощь приветствуется!

library(data.table) 

a = c(2,2.5,2,4)
b = c(4,5,8,1)
sentiment = cbind(a,b) %>% 
  as.data.frame()

setDT(sentiment)[, paste0(names(sentiment), "_delta") := lapply(.SD, function(x) shift(x, 1L, 
type="lag")/x -1)]

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

Вот базовое решение R с использованием sapply, переданное в функцию в lapply, которая перебирает столбцы настроения с желаемыми именами выходных столбцов, используя setNames.

sentiment <- data.frame(a = c(2,3,1,9), b = c(4,5,8,1))
calc_lag <- function(x) {
  c(NA, round(sapply(2:length(x), function(y) {
    (x[y] - x[y-1]) / x[y-1]
  }), 1))
}
cbind(sentiment, lapply(setNames(sentiment, paste0(colnames(sentiment), '_lag')), calc_lag))
#  a b a_lag b_lag
#1 2 4    NA    NA
#2 3 5   0.5   0.2
#3 1 8  -0.7   0.6
#4 9 1   8.0  -0.9
0 голосов
/ 24 февраля 2020

Мы можем использовать diff

library(dplyr)
sentiment %>%
      mutate_all(list(delta = ~ round(c(NA, diff(.))/lag(.), 1)))

Или, если мы используем devel версию dplyr

sentiment %>% 
    mutate(across(everything(),  ~ round(c(NA, diff(.x))/lag(.x), 1), 
           names = "{col}_delta"))
#  a b a_delta b_delta
#1 2 4      NA      NA
#2 3 5     0.5     0.2
#3 1 8    -0.7     0.6
#4 9 1     8.0    -0.9
...