Разделение данных с помощью R

У меня есть некоторые данные в R, хранящиеся в data.frame, который выглядит так:

time     value
53       5
55       5
59       7
61       9
79       6
118      11
200      5

Я хотел бы разделить свои данные по времени, делая сегменты по 60 секунд (время указано в секундах). Однако я хочу создать новый data.frame, в котором будут храниться только первая и последняя записи каждого сегмента. Я понимаю, что могу легко сделать это с помощью цикла, но моя проблема заключается в том, как сказать R найти 1-й и последний элемент ведра.


person g_puffo    schedule 20.04.2014    source источник


Ответы (2)


data.table делает это удобным. Здесь столбцы добавляются для первого и последнего значения в каждую минуту:

xt <- data.table(x)
xt[,first:=head(.SD,1), by=time %/% 60]
xt[,last:=tail(.SD,1), by=time %/% 60]
xt
##    time value first last
## 1:   53     5     5    7
## 2:   55     5     5    7
## 3:   59     7     5    7
## 4:   61     9     9   11
## 5:   79     6     9   11
## 6:  118    11     9   11
## 7:  200     5     5    5

Вот один простой способ сократить это до мельчайших ведер. Измените столбец time, чтобы он указывал начало минуты, удалите столбец value и перейдите к unique:

xt$time <- 60 * xt$time %/% 60
xt$value <- NULL
unique(xt)
##    time first last
## 1:    0     5    7
## 2:   60     9   11
## 3:  180     5    5

Чтобы получить время и значения для первой и последней строк за каждую минуту, aggregate.data.frame работает хорошо, но вам нужны два прохода.

Первые значения:

aggregate(cbind(time, value) ~ time %/% 60, data=x, FUN=head, 1)
##   time%/%60 time value
## 1         0   53     5
## 2         1   61     9
## 3         3  200     5

Последние значения:

aggregate(cbind(time, value) ~ time %/% 60, data=x, FUN=tail, 1)
##   time%/%60 time value
## 1         0   59     7
## 2         1  118    11
## 3         3  200     5

Затем они могут быть объединены в желаемый результат.

person Matthew Lundberg    schedule 20.04.2014
comment
Это выглядит очень интересно! Однако то, что я хотел бы сделать, это создать новый data.frame или data.table, состоящий из ВСЕЙ строки (следовательно, мне нужно значение time и value для этой записи) 1-го и последнего элемента ведра, а не просто запись для value 1-го и последнего элемента ведра. - person g_puffo; 21.04.2014
comment
+1, также: xt[xt[, .I[c(1L, if (.N>=2L) .N)], by=time%/%60L]$V1] - person Arun; 26.04.2014

Похоже, что время увеличивается, поэтому это дает подмножество строк, которые являются первыми или последними в каждом сегменте 60 секунд.

subset(DF, time %in% unlist(tapply(time, time %/% 60 * 60, range)))

давая:

  time value
1   53     5
3   59     7
4   61     9
6  118    11
person G. Grothendieck    schedule 20.04.2014