2015-11-05 3 views
1

У меня есть таблица, подобная следующие:Reshape таблицы для создания временных рядов агрегированного префикса

name,time_in,time_out 
jim,1/1/2000 08:24,1/1/2000 15:24 
jim,1/2/2000 08:13,1/2/2000 16:24 
jim,1/3/2000 08:14,1/3/2000 15:25 
jim,1/4/2000 08:33,1/4/2000 16:23 
linda,1/1/2000 08:24,1/1/2000 15:24 
mark,1/2/2000 08:13,1/2/2000 16:24 
mark,1/3/2000 08:14,1/3/2000 15:25 
mark,1/4/2000 08:33,1/4/2000 16:23 

игнорировать фактическое время, точка дней не выстраиваются в линии. Большая часть того, что я видел для переформатирования, имеет все красивое и квадратное, где мои данные могут в конечном итоге быть редкими. Есть простой способ (в поисках решений R, но открыты для Excel или что-нибудь быстро), чтобы создать агрегацию таблицу, аналогичную следующей:

jim,1/1/2000 08:24,1/1/2000 15:24,1/2/2000 08:13,1/2/2000 16:24,1/3/2000 08:14,1/3/2000 15:25,1/4/2000 08:33,1/4/2000 16:23 
linda,1/1/2000 08:24,1/1/2000 15:24 
mark,1/2/2000 08:13,1/2/2000 16:24,1/3/2000 08:14,1/3/2000 15:25,1/4/2000 08:33,1/4/2000 16:23 

Где каждый человек агрегируются в один ряд (не знаю, как для обработки заголовков либо в данный момент, открыт для предложений.)

+0

Хорошее качество даже не первый вопрос - молодец (и Добро пожаловать!). – pnuts

ответ

1

Рассмотрим базовый R решение, которое использует текущий счет на различных имен и перекраивает долго широко по количеству:

# RECREATING DATA FRAME 
df <- data.frame(name = c("Jim", "Jim", "Jim", "Jim", "linda", "mark", "mark", "mark"), 
     time_in = c("1/1/2000 8:24", "1/2/2000 08:13", "1/3/2000 08:14", "1/4/2000 08:33", 
        "1/1/2000 08:24", "1/2/2000 08:13", "1/3/2000 08:14", "1/4/2000 08:33"), 
     time_out = c("1/1/2000 15:24", "1/2/2000 16:24", "1/3/2000 15:25", "1/4/2000 16:23", 
        "1/1/2000 15:24", "1/2/2000 16:24", "1/4/2000 15:25", "1/4/2000 16:23")) 

# COUNTING BY GROUPED NAMES 
df$numcount <- sapply(1:nrow(df), 
         function(i) sum(df[1:i, c("name")] == df$name[i])) 

# RESHAPING LONG TO WIDE 
reshapedf <- reshape(df, v.names = c("time_in", "time_out"), 
          timevar=c("numcount"), idvar = c("name"), 
          direction = "wide") 

row.names(reshapedf) <- NULL 

reshapedf 

ВЫВОД

name  time_in.1  time_out.1  time_in.2  time_out.2  time_in.3  time_out.3  time_in.4  time_out.4 
1 Jim 1/1/2000 8:24 1/1/2000 15:24 1/2/2000 08:13 1/2/2000 16:24 1/3/2000 08:14 1/3/2000 15:25 1/4/2000 08:33 1/4/2000 16:23 
2 linda 1/1/2000 08:24 1/1/2000 15:24   <NA>   <NA>   <NA>   <NA>   <NA>   <NA> 
3 mark 1/2/2000 08:13 1/2/2000 16:24 1/3/2000 08:14 1/4/2000 15:25 1/4/2000 08:33 1/4/2000 16:23   <NA>   <NA> 
1

в предположении, что все линии должны быть объединены под тем же названием являются смежными, это Python скрипт

from itertools import groupby 

with open('infile.txt') as in_f, open('outfile.txt', 'w') as out_f: 
    next(in_f) # skip header 
    aggr = groupby(in_f, lambda line: line.partition(',')[0]) 
    for k, lines in aggr: 
     slines = (l.lstrip(k+',').rstrip() for l in lines) 
     out_line = k+','+','.join(slines)+'\n' 
     out_f.write(out_line) 

делает трюк.

Например, при входном файле

name,time_in,time_out 
jim,1/1/2000 08:24,1/1/2000 15:24 
jim,1/2/2000 08:13,1/2/2000 16:24 
jim,1/3/2000 08:14,1/3/2000 15:25 
jim,1/4/2000 08:33,1/4/2000 16:23 
linda,1/1/2000 08:24,1/1/2000 15:24 
mark,1/2/2000 08:13,1/2/2000 16:24 
mark,1/3/2000 08:14,1/3/2000 15:25 
mark,1/4/2000 08:33,1/4/2000 16:23 

производит выходной файл

jim,1/1/2000 08:24,1/1/2000 15:24,1/2/2000 08:13,1/2/2000 16:24,1/3/2000 08:14,1/3/2000 15:25,1/4/2000 08:33,1/4/2000 16:23 
linda,1/1/2000 08:24,1/1/2000 15:24 
mark,1/2/2000 08:13,1/2/2000 16:24,1/3/2000 08:14,1/3/2000 15:25,1/4/2000 08:33,1/4/2000 16:23 

Он использует мощь itertools.groupby

В основном, он держит группируя строки как если префикс (то есть имя) не изменяется. Когда это произойдет, он будет создан, создав еще одну группу на вновь найденном префиксе. Затем он просто соединяет элементы каждой группы на одной строке, разделенных «»

Примечание: в случае, если вы хотите, чтобы заголовок появится в выходном файле, измените строку

next(in_f) # skip header 

в

out_f.write(next(in_f)) # write and skip header