Расчет движущихся различий между столбцами в строке - PullRequest
0 голосов
/ 01 июня 2018

Я хотел бы выполнять вычисления по столбцам в моих данных, по строкам.Расчеты «движутся» в том смысле, что я хотел бы знать разницу между двумя числами в столбцах 1 и 2, затем в столбцах 3 и 4 и так далее.Я посмотрел на функции «loop» и «rollapply», но не смог понять это.Ниже приведены три варианта того, что было предпринято.Только третий вариант дает мне результат, которого я добиваюсь, но это очень длинный код, а также не позволяет автоматизировать (входные данные будут иметь гораздо большую матрицу, поэтому ввод вычисления для каждой строки не будет работать).Посоветуйте, пожалуйста, как сделать этот код короче и / или какие-либо другие пакеты / функции, чтобы узнать, кто будет выполнять эту работу.СПАСИБО!

МОЙ ТЕСТ-СЦЕНАРИЙ В R + ошибки / результаты

Пример набора данных

 a<- c(1,2,3, 4, 5)
 b<- c(1,2,3, 4, 5)
 c<- c(1,2,3, 4, 5)
 test.data <- data.frame(cbind(a,b*2,c*10))
 names(test.data) <- c("a", "b", "c")

Пример расчета попытки:

ОПЦИЯ 1

require(zoo)
rollapply(test.data, 2, diff, fill = NA, align = "right", by.column=FALSE)

РЕЗУЛЬТАТ 1 (не то, что нам нужно. То, что нам нужно, находится внизу варианта 3)

#     a  b  c
#[1,] NA NA NA
#[2,]  1  2 10
#[3,]  1  2 10
#[4,]  1  2 10
#[5,]  1  2 10

ВАРИАНТ 2:

results <- for (i in 1:length(nrow(test.data))) {
diff(as.numeric(test.data[i,]), lag=1)
print(results)}

РЕЗУЛЬТАТ 2: (опять не то, что мы ищем)

# NULL

ВАРИАНТ 3: работает, но долгий путь, поэтому хотел бы упростить код и сделать общий для любой длины наблюдений в моем фрейме данных и любого числастолбцов (то есть более 3).Я хотел бы «автоматизировать» приведенные ниже шаги, если известно количество наблюдений (т. Е. Рядов).

row1=diff(as.numeric(test[1,], lag=1))
row2=diff(as.numeric(test[2,], lag=1))
row3=diff(as.numeric(test[3,], lag=1))
row4=diff(as.numeric(test[4,], lag=1))
row5=diff(as.numeric(test[5,], lag=1))

results.OK=cbind.data.frame(row1, row2, row3, row4, row5)
transpose.results.OK=data.frame(t(as.matrix(results.OK)))
names(transpose.results.OK)=c("diff.ab", "diff.bc")
Final.data = transpose.results.OK
print(Final.data)

РЕЗУЛЬТАТ 3: (ЭТО ТО, ЧТО Я ХОЧУ ПОЛУЧИТЬ, «row1» может быть «obs1»"и т.д.)

#     diff.ab diff.bc
#row1       1       8
#row2       2      16
#row3       3      24
#row4       4      32
#row5       5      40

КОНЕЦ

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

Решение на основе apply с использованием diff по строкам может быть получено как:

# Result
res <- t(apply(test.data, 1, diff)) #One can change it to data.frame

# Name of the columns
colnames(res) <-  paste0("diff.", head(names(test.data), -1),
                               tail(names(test.data), -1))

res
#      diff.ab diff.bc
# [1,]       1       8
# [2,]       2      16
# [3,]       3      24
# [4,]       4      32
# [5,]       5      40
0 голосов
/ 01 июня 2018

Вот 3 переделанных варианта плюс 4-й вариант:

# 1
library(zoo)
d <- t(rollapplyr(t(test.data), 2, diff, by.column = FALSE))

# 2
d <- test.data[-1]
for (i in 1:nrow(test.data)) d[i, ] <- diff(unlist(test.data[i, ]))

# 3
d <- t(diff(t(test.data)))

# 4 - also this works
nc <- ncol(test.data)
d <- test.data[-1] - test.data[-nc]

Для любого из них установить имена:

colnames(d) <- paste0("diff.", head(names(test.data), -1), colnames(d))

(2) и (4) дать этоdata.frame и (1) и (3) дают соответствующую матрицу:

> d
  diff.ab diff.bc
1       1       8
2       2      16
3       3      24
4       4      32
5       5      40

Используйте as.matrix или as.data.frame, если хотите другой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...