重塑 table 以创建按前缀聚合的时间序列
Reshape table to create time series aggregated by prefix
我有一个 table 类似于以下内容:
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
忽略实际时间,重点是天数不一致。我在 re-shaping 中看到的大部分内容都很好而且方正,我的数据最终可能会被稀疏重塑。有没有一种简单的方法(寻找 R 解决方案,但对 Excel 或任何快速开放)来创建类似于以下内容的 table 聚合:
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
其中每个人聚合到一行(此时也不知道如何处理headers,欢迎提出建议。)
假设所有要聚合的同名行都是连续的,这个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
的力量
基本上,只要前缀(即名称)不变,它就会对行进行分组。当它这样做时,它继续前进,在新发现的前缀上创建另一个组。
然后它简单地将每个组的元素连接在一行上,用 ','
分隔
注意:如果您希望 header 出现在输出文件中,请更改行
next(in_f) # skip header
到
out_f.write(next(in_f)) # write and skip header
考虑这个基本的 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>
我有一个 table 类似于以下内容:
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
忽略实际时间,重点是天数不一致。我在 re-shaping 中看到的大部分内容都很好而且方正,我的数据最终可能会被稀疏重塑。有没有一种简单的方法(寻找 R 解决方案,但对 Excel 或任何快速开放)来创建类似于以下内容的 table 聚合:
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
其中每个人聚合到一行(此时也不知道如何处理headers,欢迎提出建议。)
假设所有要聚合的同名行都是连续的,这个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
的力量
基本上,只要前缀(即名称)不变,它就会对行进行分组。当它这样做时,它继续前进,在新发现的前缀上创建另一个组。 然后它简单地将每个组的元素连接在一行上,用 ','
分隔注意:如果您希望 header 出现在输出文件中,请更改行
next(in_f) # skip header
到
out_f.write(next(in_f)) # write and skip header
考虑这个基本的 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>