Если мы знаем положение столбца «Дата», используйте метод индексации, чтобы удалить столбец
f1 <- function(x) (-diff(x)/x[-length(x)])
apply(df[-1], 2, f1)
Или, чтобы сделать его менее подверженным ошибкам, удалите столбец с помощью name
apply(df[setdiff(names(df), 'Data')], 2, f1)
apply
преобразуется в matrix
, а matrix
может иметь только один тип.Итак, что происходит, это то, что класс Date
приводится в режим целочисленного хранения, если он также включен.
Если есть столбцы character
, все элементы будут преобразованы в character
, и вычисление не будет работать
Функция diff
возвращает вывод с length
меньше length
входных данных, и если нам нужно обновить исходные столбцы набора данных, будет length
несоответствие.Чтобы избежать этого, добавьте NA
в начале
f2 <- function(x) (c(NA, -diff(x)/x[-length(x)]))
df[-1] <- apply(df[-1],2, f2)
Если мы создаем новые столбцы
df[paste0(names(df)[-1], "_diffs")] <- apply(df[-1],2, f2)
Или чтобы сделать его более динамичным
i1 <- sapply(df, is.numeric)
apply(df[i1], 2, f1)
Кроме того, для наборов данных нескольких типов можно использовать lapply/sapply
lapply(df[i1], function(x) -diff(x)/x[-length(x)])
С dplyr
мы можем использовать mutate_if
library(dplyr)
df %>%
mutate_if(is.numeric, ~ c(NA_real_, diff(.)/.[-n()]))
# Data A B C D
#1 2019-09-19 NA NA NA NA
#2 2019-09-18 -0.010277492 -0.01045857 -0.016852703 -0.006208609
#3 2019-09-17 0.008826584 -0.01524390 -0.017809439 -0.014993753
#4 2019-09-16 0.000514668 -0.02992776 -0.023798731 -0.013742072
#5 2019-09-13 -0.017489712 0.09234043 -0.001625261 0.010503751
если нам нужно создать новые столбцы, поместите их в list
и сделайте именование как в list
df %>%
mutate_if(is.numeric, list(diffs = ~ c(NA_real_, diff(.)/.[-n()])))
# Data A B C D A_diffs B_diffs C_diffs D_diffs
#1 2019-09-19 19.46 49.72 45.69 48.32 NA NA NA NA
#2 2019-09-18 19.26 49.20 44.92 48.02 -0.010277492 -0.01045857 -0.016852703 -0.006208609
#3 2019-09-17 19.43 48.45 44.12 47.30 0.008826584 -0.01524390 -0.017809439 -0.014993753
#4 2019-09-16 19.44 47.00 43.07 46.65 0.000514668 -0.02992776 -0.023798731 -0.013742072
#5 2019-09-13 19.10 51.34 43.00 47.14 -0.017489712 0.09234043 -0.001625261 0.010503751