2014-01-24 2 views
1

У меня есть данные временных рядов как data.table class и каждый столбец (точки наблюдения) имеют значения, которые я хочу подсчитать в скользящем окне (30 ширины). Я попытался использовать rle (sort (x)) для подсчета всех значений в rollapply, но он не работает.rollapply с функцией rle (x)

, например, если у меня есть таблица, как показано ниже,

dt <- data.frame(v1=c(1,0,1,4,4,4,4,4),v2=c(1,1,1,4,3,3,3,3), 
      v3=c(0,1,1,3,3,3,3,2),v4=c(1,1,0,3,3,3,3,3), 
     v5=c(1,1,1,5,5,5,5,5)) 

Я попытался, как это;

rollapply(dt, 3, function(x) {rle(sort(x))$values; rle(sort(x))$length}) 

но результат просто не имеет смысла. пожалуйста, дайте мне какое-то направление ...

+0

я не вижу любой 'data.table' выше. Но что более важно, неясно, чего вы хотите - пожалуйста, укажите желаемый результат. – eddi

+0

извините за непонятный вопрос. желаемый результат был для каждого скользящего окна, в котором я хотел иметь отсортированное значение с номером появления (подсчета). Я могу сделать свой dt в dt1 <-data.table (dt) – kclick

ответ

2

Решение 1 Предполагая, что цель состоит в том, чтобы получить прокатки отсчеты 3 значений, попробуйте следующее:

m <- as.matrix(dt) 
levs <- sort(unique(c(m))) 
f <- function(x) table(factor(x, levs)) 
r <- rollapply(m, 3, f) 

Здесь levs является 0, 1, ..., 5, поэтому для каждого применения функции мы выберем вектор 6 длиной с числом 0, 1, ..., 5. Есть 5 входных столбцов, поэтому применение такой функции к каждому столбцу дает 5 * 6 = 30 столбцов вывода.

Обратите внимание, что rollapply работает с объектами-матрицами или зоопарками, а не с кадрами данных, поэтому мы его преобразовали. Кроме того, чтобы каждое приложение функции выводило вектор той же длины, мы преобразуем каждый вход в коэффициент с одинаковыми уровнями.

Обратите внимание, что:

ra <- array(r, c(6, 6, 5)) 

дает 3d массив, в котором ра [,, я] является матрица, образованная rollapply(dt[, i], 3, f). То есть в матрице ra[,,i] есть строка для каждого приложения f в столбце i, а столбцы в этой строке подсчитывают число 0, 1, 5,.

Другая возможность заключается в следующем, который дает те же 5 матриц (по одному на каждый входной столбец) в качестве компонентов полученного списка:

lapply(dt, rollapply, 3, f) 

В качестве примера рассмотрим следующее. Строка 1 выхода говорит, что первое приложение f на dt[,1] имеет один 0, два 1s и другие значения. Это также может быть получен из r[,,1] или lapply(dt, rollapply, 3, f)[[1]]:

> rollapply(dt[, 1], 3, f) 
    0 1 2 3 4 5 
[1,] 1 2 0 0 0 0 <- dt[1:3,1] has 1 zero and 2 ones 
[2,] 1 1 0 0 1 0 <- dt[2:4,1] has 1 zero and 1 one and 1 four, etc. 
[3,] 0 1 0 0 2 0 
[4,] 0 0 0 0 3 0 
[5,] 0 0 0 0 3 0 
[6,] 0 0 0 0 3 0 

Решение 2

Это говорит, глядя на ячейку 1,1 выхода, что есть один 0 и два 1s в dt[1:3,1]. Глядя на ячейку 2,1 на выходе мы видим, что есть один 0, один 1 и 1 четыре в dt[2:4,1] и т.д.

> g <- function(x) { tab <- table(x); toString(paste(names(tab), tab, sep = ":")) } 
> sapply(dt, rollapply, 3, g) # or rollapply(m, 3, g) where m was defined in solution 1 
    v1    v2    v3   v4    v5   
[1,] "0:1, 1:2"  "1:3"   "0:1, 1:2" "0:1, 1:2"  "1:3"  
[2,] "0:1, 1:1, 4:1" "1:2, 4:1"  "1:2, 3:1" "0:1, 1:1, 3:1" "1:2, 5:1" 
[3,] "1:1, 4:2"  "1:1, 3:1, 4:1" "1:1, 3:2" "0:1, 3:2"  "1:1, 5:2" 
[4,] "4:3"   "3:2, 4:1"  "3:3"  "3:3"   "5:3"  
[5,] "4:3"   "3:3"   "3:3"  "3:3"   "5:3"  
[6,] "4:3"   "3:3"   "2:1, 3:2" "3:3"   "5:3"  

ДОБАВЛЕНО: Дополнительное обсуждение и решение 2.

+0

Благодарим вас за ответ.но очень сложно интерпретировать результат. то, что я действительно хочу получить, - если я просто использую данные выше dt, используя 5-кратное скользящее окно. Для столбца v1 для первого скользящего окна 1 имеет 2 counts, 0's 1, 4's 2, во втором скользящем окне, 1's 1, 0's 1, 4's 3 counts. и т. д. Поэтому, когда я просто запускаю rle (sort (x)) x как простой вектор, вы получаете отсортированные значения результата с общим количеством отсчетов. Это то, что я хочу иметь в своем скользящем окне, но ... Я не знаю, почему функция rle не очень хорошо применяется в функции rollapply. – kclick

+0

Проблема с кодом в вопросе заключается в том, что функция, данная 'rollapply', возвращает выходы различной длины в зависимости от входных значений, поэтому он не может сделать результат в прямоугольник. Я добавил дополнительное обсуждение и второе решение. –

+0

Это было очень полезно. Я попытаюсь переварить все и дам вам знать, есть ли у меня еще один вопрос относительно вашего подхода. – kclick