3

我在 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)

谢谢!

4

3 回答 3

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)

然后相应地重命名您的尺寸。提供实际测试用例时提供的测试代码。

于 2013-02-20T23:56:03.850 回答
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和)的单个结果 ( x$hour)。里面的小公式acast让您表达您希望如何配置新数据集 - 波浪号左侧的变量名称用于定义行,右侧的变量名称用于定义列。在这种情况下,只剩下一列 - x$value- 所以它会自动用于填充结果matrix

我花了一些时间来思考所有这些问题,但考虑重塑数据是一件非常强大的事情。

于 2013-02-20T23:57:24.013 回答
1

xtabs这在基础 R中非常简单:

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"))
于 2013-02-21T04:50:01.163 回答