我在R中有一个3x168数据帧。每行有三列 - 日,小时和值。日期和小时对应于星期几,小时列对应于当天的小时,该值对应于我所关注的值。
我希望转换这些数据,使其存在于24x7矩阵中,其中一行(或列)对应于特定日期,而一列(或行)对应于特定小时。
在R中执行此操作的最有效方法是什么?我已经能够将一些混乱的命令串起来以获得接近的东西,但我觉得有一个非常有效的解决方案。
示例起始数据:
> print(data)
weekday hour value
1 M 1 1.11569683
2 M 2 -0.44550495
3 M 3 -0.82566259
4 M 4 -0.81427790
5 M 5 0.08277568
6 M 6 1.36057839
...
156 SU 12 0.12842608
157 SU 13 0.44697186
158 SU 14 0.86549961
159 SU 15 -0.22333317
160 SU 16 1.75955163
161 SU 17 -0.28904472
162 SU 18 -0.78826607
163 SU 19 -0.78520233
164 SU 20 -0.19301032
165 SU 21 0.65281161
166 SU 22 0.37993619
167 SU 23 -1.58806896
168 SU 24 -0.26725907
我希望得到类型的东西:
M .... SU
1 1.11569683
2 -0.44550495
3 -0.82566259
4 -0.81427790
5
6
.
.
.
19
20
21 0.65281161
22 0.37993619
23 -1.58806896
24 -0.26725907
您可以通过这种方式获得一些实际的样本数据:
weekday <- rep(c("M","T","W","TH","F","SA","SU"),each=24)
hour <- rep(1:24,7)
value <- rnorm(24*7)
data <- data.frame(weekday=weekday, hour=hour, value=value)
谢谢!
答案 0 :(得分:3)
像这样(假设dfrm是数据对象):
M <- matrix( NA, nrow=24, ncol=2,
dimnames = list(Hours = 1:24, Days=unique(dfrm$weekday) ) )
M[ cbind(dfrm$hour, dfrm$weekday) ] <- dfrm$value
> M
Days
Hours M SU
1 1.11569683 NA
2 -0.44550495 NA
3 -0.82566259 NA
4 -0.81427790 NA
5 0.08277568 NA
6 1.36057839 NA
7 NA NA
8 NA NA
9 NA NA
10 NA NA
11 NA NA
12 NA 0.1284261
13 NA 0.4469719
14 NA 0.8654996
15 NA -0.2233332
16 NA 1.7595516
17 NA -0.2890447
18 NA -0.7882661
19 NA -0.7852023
20 NA -0.1930103
21 NA 0.6528116
22 NA 0.3799362
23 NA -1.5880690
24 NA -0.2672591
或者如果它们“密集”,你可以“折叠价值”:
M <- matrix(dfrm$value, 24, 7)
然后相应地重命名您的尺寸。提供实际测试用例时提供的测试代码。
答案 1 :(得分:3)
使用reshape2
包时,这非常简单:
# Sample data - please include some with your next question!
x <- data.frame(day = c(rep("Sunday", 24),
rep("Monday", 24),
rep("Tuesday", 24),
rep("Wednesday", 24),
rep("Thursday", 24),
rep("Friday", 24),
rep("Saturday", 24)),
hour = rep(1:24, 7),
value = rnorm(n = 24 * 7)
)
library(reshape2)
# For rows representing hours
acast(x, hour ~ day)
# For rows representing days
acast(x, day ~ hour)
# If you want to preserve the ordering of the days, just make x$day a factor
# unique(x$day) conveniently gives the right order here, but you'd always want
# check that (and make sure the factor reflects the original value - that's why
# I'm making a new variable instead of overwriting the old one)
x$day.f <- factor(x$day, levels = unique(x$day))
acast(x, hour ~ day.f)
acast(x, day.f ~ hour)
您拥有的三列数据集是所谓“熔融数据”的示例 - 每行代表一个带有一个或多个标识符的结果(x$value
)(此处为x$day
和{{ 1}})。 x$hour
中的小公式让您可以表达您希望如何配置新数据集 - 波浪号左侧的变量名用于定义行,右侧的变量名用于定义列。在这种情况下,只剩下一列 - acast
- 所以它会自动用于填写结果x$value
。
我花了一段时间才把我的大脑包裹在所有这些中,但考虑重塑数据是非常有用的。
答案 2 :(得分:1)
基础R中的xtabs
非常简单:
output <- as.data.frame.matrix(xtabs(value ~ hour + weekday, data))
head(output)
# SU M T W TH F SA
# 1 -0.56902302 -0.4434357 -1.02356300 -0.38459296 0.7098993 -0.54780300 1.5232637
# 2 0.01023058 -0.2559043 -2.79688932 -1.65322029 -1.5150986 0.05566206 -0.6706817
# 3 0.18461405 1.2783761 -0.02509352 -1.36763623 -0.4978633 0.20300678 1.4211054
# 4 0.54194889 0.5681317 0.69391876 -1.35805959 0.4208977 1.65256590 0.3622756
# 5 -1.68048536 -1.9274994 0.24036908 -0.21959772 0.7654983 1.62773579 0.6760743
# 6 -1.39398673 1.7251476 0.36563174 0.04554249 -0.2991433 -1.47331314 -0.7647513
要按照正确的顺序(如上所述)获取日期,请在执行factor
步骤之前在“工作日”变量上使用xtabs
:
data$weekday <- factor(data$weekday,
levels = c("SU", "M", "T", "W", "TH", "F", "SA"))