在R中从数据框中提取/重塑数据

3
我有一个数据框,你可以使用以下代码重新创建它的样本:
df = data.frame(M_id = c(rep(1000,8),rep(1001,8)), Day = c(rep(1,4),rep(2,4),rep(1,4),rep(2,4)), Half_hr = rep(1:4,4) ,Val = c(0.25,0.1,0.2,0.4,0.3,0.6,0.35,0.5,0.15,0.2,0.3,0.5,0.4,0.7,0.45,0.6))

看起来是这样的:
>df : 

 M_id  Day  Half_hr     Val
 1000    1   1          0.25
 1000    1   2          0.1
 1000    1   3          0.2
 1000    1   4          0.4
 1000    2   1          0.3
 1000    2   2          0.6
 1000    2   3          0.35
 1000    2   4          0.5
 1001    1   1          0.15
 1001    1   2          0.2
 1001    1   3          0.3
 1001    1   4          0.5
 1001    2   1          0.4
 1001    2   2          0.7
 1001    2   3          0.45
 1001    2   4          0.6

在这里,每行中的Val表示该M_id在该Day的该Half_hr(Half_hr:1,2为第1个小时,3,4为第2个小时,依此类推)的值。我的实际数据有许多Ids、Days和48个Half_hrs(对应24小时)的Val。

现在,我想将每个M_id每天的每个Half_hr的数据汇总到每个小时。

我的输出应该如下所示:

>df:

M_id    Day Hour_1  Hour_2
1000    1    0.35    0.6
1000    2    0.9     0.85
1001    1    0.35    0.8
1001    2    0.11    1.05

示例为M_id = 1000,Day = 1,Hour_1 = Val(Half_hr-1 + Half_hr-2)= 0.25+0.1 = 0.35。类似地,对于Hour_2 = val(Half_hr-3 + Half_hr-4)= 0.2+0.4 = 0.6

我使用for循环和sqldf完成了这项工作,但是花费了大量时间。

由于我要处理的数据有1000个M_id,每个M_id有535天,每天有48个半小时(24小时数据),因此我请求优化后的代码。

2个回答

3
我们可以使用 data.table。将 'data.frame' 转换为 'data.table' (setDT(df))。在按 "M_id"、"Day" 进行分组后,使用 gl 创建分组变量,然后使用 dcast 将格式从 'long' 转换为 'wide'。
library(data.table)
df1 <- setDT(df)[order(M_id,Day, Half_hr)][,
         gr:=gl(.N, 2, .N) , .(M_id ,Day)][]
dcast(df1, M_id+Day~paste0("Hour_", gr), value.var="Val", sum)
#   M_id Day Hour1 Hour2
#1: 1000   1  0.35  0.60
#2: 1000   2  0.90  0.85
#3: 1001   1  0.35  0.80
#4: 1001   2  1.10  1.05

这是否假设Half_hr是有序的? - Roman Luštrik
@RomanLuštrik 我之前也是这么认为的,但在你的评论后,我对数据进行了order - akrun

3

以下是使用基本R解决方案,使用 transform()aggregate()reshape()

reshape(aggregate(Val~.,transform(df,Hour=(Half_hr-1L)%/%2L+1L,Half_hr=NULL),sum),dir='w',idvar=c('M_id','Day'),timevar='Hour');
##   M_id Day Val.1 Val.2
## 1 1000   1  0.35  0.60
## 2 1001   1  0.35  0.80
## 3 1000   2  0.90  0.85
## 4 1001   2  1.10  1.05

它也运行得非常好。但是相比之下,使用data.table的解决方案对我的数据来说更快。非常感谢。 - Karthaveeryarjun Vinjamoori

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接