这个几乎是一个挑战!
我有以下数据框:
tag hour val
N1 2013-01-01 00:00:00 0.3404266179
N1 2013-01-01 01:00:00 0.3274182995
N1 2013-01-01 02:00:00 0.3142598749
N2 2013-01-01 02:00:00 0.3189924887
N2 2013-01-01 04:00:00 0.3170907762
N3 2013-01-01 05:00:00 0.3161910788
N3 2013-01-01 06:00:00 0.4247638954
我需要把它变成这样的东西:
hour N1 N2 N3
2013-01-01 00:00:00 0.3404266179 NULL NULL
2013-01-01 01:00:00 0.3274182995 NULL NULL
2013-01-01 02:00:00 0.3142598749 0.3189924887 NULL
2013-01-01 03:00:00 NULL NULL NULL
2013-01-01 04:00:00 NULL 0.3170907762 NULL
2013-01-01 05:00:00 NULL NULL 0.3161910788
2013-01-01 06:00:00 NULL NULL 0.4247638954
由于事情并不那么容易,我的数据框架达到N5000,每小时有近200,000个条目。
时间戳表现得非常好,因为它可以通过简单的命令strptime("2013-01-01 00:00:00", "%Y-%m-%d %H:%M:%S") + c(0:172800)*60
(172800分钟~4个月)生成所有时间戳的方式逐步增加每个人。但不一定你有每个时间戳的数据,正如我在示例中所示。
我知道我可以编写一个带有无限循环的函数,但是有没有办法只使用R(及其包)函数来做到这一点?
谢谢!
答案 0 :(得分:3)
你想使用" reshape2"包:
install.packages("reshape2")
library(reshape2)
newdf <- dcast(mydata, hour~tag)
reshape2是一个非常强大的软件包,我完全无法理解......但有时它有很好的有用的东西,只是工作。 : - )
更新:那是&#34; dcast&#34;不是&#34;演员&#34; ...我错误地使用了&#34;重塑&#34;不是&#34; reshape2&#34;包。固定!
答案 1 :(得分:2)
这既不是最直接也不优雅的解决方案,但它有效:
示例data.frame:
df <- data.frame(tag=rep(c("N1", "N2", "N4"), c(3,2,2)),
hour=structure(c(1,2,3,3,5,6,7), class="POSIXct"),
val=runif(7))
## tag hour val
## 1 N1 1970-01-01 01:00:01 0.6645598
## 2 N1 1970-01-01 01:00:02 0.7924186
## 3 N1 1970-01-01 01:00:03 0.3813311
## 4 N2 1970-01-01 01:00:03 0.8555780
## 5 N2 1970-01-01 01:00:05 0.4480540
## 6 N4 1970-01-01 01:00:06 0.1875233
## 7 N4 1970-01-01 01:00:07 0.5755332
现在我们创建生成的date
列(它只是一个示例):
uh <- structure(1:7, class="POSIXct") # or e.g. uh <- unique(df$hour), or seq(), etc.
然后我们创建一个&#34;空&#34;结果数据帧(每个val将为NA)
nr <- length(uh) # number of rows on out
# column definitions:
(coldef <- paste("hour=uh", paste(unique(df$tag), "NA_real_", sep="=", collapse=", "), sep=", "))
## [1] "hour=uh, N1=NA_real_, N2=NA_real_, N4=NA_real_"
# create output df:
outdf <- eval(parse(text=sprintf("data.frame(list(%s))", coldef)))
最后,让我们在每个N*
列中设置值:
for (idx in split(1:nrow(df), df$tag))
outdf[outdf$hour %in% df$hour[idx], as.character(df$tag[idx[1]])] <- df$val[idx]
答案 2 :(得分:2)
如果您不想打扰其他软件包,也可以考虑基本函数reshape
。使用@ gagolews的样本数据
> reshape(df, idvar="hour", timevar="tag", v.names="val", direction="wide")
hour val.N1 val.N2 val.N4
1 1969-12-31 19:00:01 0.8156553 NA NA
2 1969-12-31 19:00:02 0.9203821 NA NA
3 1969-12-31 19:00:03 0.8127614 0.7386737 NA
5 1969-12-31 19:00:05 NA 0.9648562 NA
6 1969-12-31 19:00:06 NA NA 0.2540216
7 1969-12-31 19:00:07 NA NA 0.5024042