2012-12-26 4 views
3

Веселого Рождествараскол DataFrame

Я хотел бы разделить длинный фрейм данных. Dataframe выглядит следующим образом

x<-c('0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00', 
    '0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00', 
    '3:30:00', '4:00:00','0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', 
    '2:30:00', '3:00:00', '0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', 
    '2:30:00', '3:00:00' , '3:30:00', '4:00:00') 

    y=seq(1:32) 

    data1=data.frame(x,y) 

я хочу разделить таким образом, что вывод выглядит

0:00:00 1 8 17 24 
    0:30:00 2 9 18 25 
    1:00:00 3 10 19 26 
    1:30:00 4 11 20 27 
    2:00:00 5 12 21 28 
    2:30:00 6 13 22 29 
    3:00:00 7 14 23 30 
    3:30:00 NA 15 NA 31 
    4:00:00 NA 16 NA 32 

какие-либо идеи или функции, которые я смотрю на это делать? Я попытался использовать функцию split, но не смог ее сделать. Большое спасибо за вашу помощь и время.

Решение, приведенное ниже, Мэтью работает лучше всего. Однако, если я увеличить время цикла для й

x<-c('0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00', '3:30:00', 
    '4:00:00', '4:30:00', '5:00:00', '5:30:00', '6:00:00', '6:30:00', '7:00:00', 
    '7:30:00','8:00:00', '8:30:00', '9:00:00', '9:30:00', '10:00:00', '10:30:00', 
    '11:00:00','11:30:00','0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', 
    '3:00:00', '3:30:00', '4:00:00', '4:30:00', '5:00:00', '5:30:00', '6:00:00', '6:30:00', 
    '7:00:00', '7:30:00','8:00:00', '8:30:00', '9:00:00', '9:30:00', '10:00:00', '10:30:00', 
    '11:00:00','11:30:00', '12:00:00', '12:30:00', '13:00:00', '13:30:00') 

и использовать тот же самый код, я получаю следующее сообщение об ошибке:

Error in match.names(clabs, names(xi)) : names do not match previous names 

Приветствии, Swagath

+0

Ваш столбец 'x' не является случайным случаем несколько раз за несколько дней? Если это так, вы можете лучше разобрать всю дату и работать с этим. – A5C1D2H2I1M1N2O1R2T1

+0

Часть даты даты будет естественным фактором для разделения, лучше, чем поиск регрессии во времени. –

ответ

1

Если мы можем предположить, что каждый новый цикл начинается в 0:00:00 и что каждый новый цикл всегда будет включать в себя 0:00:00, то можно легко использовать reshape() после создания «время» переменной с помощью cumsum().

data1 <- data.frame(
    x = c('0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', 
     '3:00:00', '0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', 
     '2:30:00', '3:00:00', '3:30:00', '4:00:00','0:00:00', '0:30:00', 
     '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00', '0:00:00', 
     '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', '3:00:00' , 
     '3:30:00', '4:00:00'), 
    y = seq(1:32)) 
data1$times <- cumsum(data1$x == "0:00:00") 
reshape(data1, direction = "wide", idvar = "x", timevar = "times") 
#   x y.1 y.2 y.3 y.4 
# 1 0:00:00 1 8 17 24 
# 2 0:30:00 2 9 18 25 
# 3 1:00:00 3 10 19 26 
# 4 1:30:00 4 11 20 27 
# 5 2:00:00 5 12 21 28 
# 6 2:30:00 6 13 22 29 
# 7 3:00:00 7 14 23 30 
# 15 3:30:00 NA 15 NA 31 
# 16 4:00:00 NA 16 NA 32 
+0

Это предположение, что я работал, чтобы избежать. Но я полагаю, что это достаточно хорошо ... –

+0

Это не нужно. Использование формата, позволяющего сравнивать порядок, позволяет удалить его. –

3

Вот данные для редактируемого вопроса :

x <- c('0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', 
     '3:00:00', '3:30:00', '4:00:00', '4:30:00', '5:00:00', '5:30:00', 
     '6:00:00', '6:30:00', '7:00:00', '7:30:00','8:00:00', '8:30:00', 
     '9:00:00', '9:30:00', '10:00:00', '10:30:00', '11:00:00','11:30:00', 
     '0:00:00', '0:30:00', '1:00:00', '1:30:00', '2:00:00', '2:30:00', 
     '3:00:00', '3:30:00', '4:00:00', '4:30:00', '5:00:00', '5:30:00', 
     '6:00:00', '6:30:00', '7:00:00', '7:30:00','8:00:00', '8:30:00', 
     '9:00:00', '9:30:00', '10:00:00', '10:30:00', '11:00:00','11:30:00', 
     '12:00:00', '12:30:00', '13:00:00', '13:30:00') 

y=seq(1:52) 

data1=data.frame(x,y) 

Нам нужно создать категориальную переменную, указывающую дни, и все, с чем мы должны работать, - это время. Если время регрессирует, предположите, что это новый день. Для этого мы преобразуем значения времени в целые числа, чтобы, используя коэффициент.

Здесь вектор lev уровней, c('0:00:00', '0:30:00', '1:00:00', ...) и фактор fac, который содержит те же строки, как данные $ х, но использует этот вектор в качестве уровней:

lev <- paste(t(outer(0:23, c('00', '30'), paste, sep=':')), '00', sep=':') 
fac <- factor(as.character(data1$x), levels=lev, ordered=TRUE) 

Теперь мы видим, когда мы регресс во время путем применения diff:

d <- c(0, diff(
    as.numeric(factor(as.character(data1$x), levels=lev, ordered=TRUE))) 
     ) 

Теперь (вдохновленное как из двух других ответов на этот вопрос), cumsum(d<0) категорических переменное, которая нам нужно, которые могут быть применен в данном фре AME, и используется для изменения формы:

data1$grp <- cumsum(d<0) 
res <- reshape(data1, direction="wide", idvar="x", timevar="grp") 

> res 
      x y.0 y.1 
1 0:00:00 1 25 
2 0:30:00 2 26 
3 1:00:00 3 27 
4 1:30:00 4 28 
5 2:00:00 5 29 
6 2:30:00 6 30 
7 3:00:00 7 31 
8 3:30:00 8 32 
9 4:00:00 9 33 
10 4:30:00 10 34 
11 5:00:00 11 35 
12 5:30:00 12 36 
13 6:00:00 13 37 
14 6:30:00 14 38 
15 7:00:00 15 39 
16 7:30:00 16 40 
17 8:00:00 17 41 
18 8:30:00 18 42 
19 9:00:00 19 43 
20 9:30:00 20 44 
21 10:00:00 21 45 
22 10:30:00 22 46 
23 11:00:00 23 47 
24 11:30:00 24 48 
49 12:00:00 NA 49 
50 12:30:00 NA 50 
51 13:00:00 NA 51 
52 13:30:00 NA 52 

Как это отличается от других ответов: он не предполагает, что день всегда будет содержать время «0:00:00», и это не требует, чтобы данные 1 $ x - переменная символа - и даже если она есть, она получает время в правильном порядке. Сравнение character скажет, что 2:00:00 происходит после 13:00:00.

+0

Очень умный подход. +1 –

+0

@MatthewLundberg Большое спасибо за ваш быстрый ответ. Тот же подход, похоже, не работает в разные моменты времени, например: – Nav

+0

@MatthewLundberg x <-c ('0:00:00', '0:30:00', '1:00:00', '1:30 : 00 ',' 2:00:00 ',' 2:30:00 ',' 3:00:00 ',' 3:30:00 ',' 4:00:00 ',' 4:30:00 ',' 5:00:00 ',' 5:30:00 ',' 6:00:00 ',' 6:30:00 ',' 7:00:00 ',' 7:30:00 ',' '8:00:00', '8:30:00', '9:00:00', '9:30:00', '10: 00: 00 ', '10: 30: 00', '11 : 00: 00 ',' 11:30:00 ',' 0:00:00 ',' 0:30:00 ',' 1:00:00 ',' 1:30:00 ',' 2:00 : 00 ',' 2:30:00 ',' 3:00:00 ',' 3:30:00 ',' 4:00:00 ',' 4:30:00 ',' 5:00:00 ',' 5:30:00 ',' 6:00:00 ',' 6:30:00 ',' 7:00:00 ',' 7:30:00 ',' 8:00:00 ',' '8: 00: 00: 00: 00: 00: 00: 00: 00: : 30: 00 ', '12: 00: 00', '12: 30: 00 ', '13: 00: 00', '13: 30: 00 ') – Nav

1

(См. Правки ниже.) Это решение создает переменную группы на основе последовательности «х» переменной, но требует, чтобы вы создаете dataframe с stringsAsFactors = FALSE или преобразовать фактор «х» с as.character():

> data1=data.frame(x,y, stringsAsFactors=FALSE) 
> data1$grp <- with(data1, cumsum(c(0 , x[-1] < x[-length(x)]))) 
> reshape(data1, direction="wide", idvar="x", timevar="grp") 
     x y.0 y.1 y.2 y.3 
1 0:00:00 1 8 17 24 
2 0:30:00 2 9 18 25 
3 1:00:00 3 10 19 26 
4 1:30:00 4 11 20 27 
5 2:00:00 5 12 21 28 
6 2:30:00 6 13 22 29 
7 3:00:00 7 14 23 30 
15 3:30:00 NA 15 NA 31 
16 4:00:00 NA 16 NA 32 

В свете редактирования : Та же стратегия должна работать, если переменная x сначала преобразуется в класс данных:

x <- as.POSIXct(x, format="%H:%M:%S") 
+0

Пожалуйста, перечитайте первое предложение в моем ответе. –

+0

О да, это удалит эту ошибку. Но тогда порядок сортировки будет некорректным для его отредактированных данных1 $ x. См. Изменение в моем ответе. –

+1

Правда. Необходимо преобразовать формат времени или даты-времени. –

Смежные вопросы