我有一个矩阵Q_hyda,有2列和n行:
[1] [2]
[1] 1950 0.265
[2] 1950 0.176
[3] 1950 0.873
. ... ...
[60] 1951 0.534
[61] 1951 0.142
. . .
. . .
. . .
. . .
[n] 2014 0.152
我想得到的是这种类型的矩阵mat_HQa:
[1950] [1951] [1952] ... [2014]
[1] 0.265 0.534 ... 0.152
[2] 0.176 0.142 ... ...
[3] 0.873 ... ... ...
. ... ... ... ...
. ... ... ... ...
. ... ... ... ...
[n] ... ... ... ...
我尝试了一些循环:
## Create a matrix mat_HQa with a_n columns (where a_n is the number of different years) and 366 rows
mat_HQa = matrix(0, 366, a_n)
colnames(mat_HQa)=as.vector(R_a) # the vector R_a is a timeline from 1950 to 2014
# fill matrix
for (i in 1:a_n)
{for (j in 1:n)
{if (R_a[i] == Q_hyda[j,1]){mat_HQa[j,i] = Q_hyda[j,2]}}}
它适用于第一列,但当它移动到第二列时,它会继续填充j的位置上的矩阵mat_HQa,我无法弄清楚如何从第一列开始填充顶部。
我对编程非常陌生,因为它不是我的主题。 我怎样才能做到这一点?我确定认为这样做更容易。 我对任何建议深表感激。
答案 0 :(得分:2)
使用reshape2
的简单方法,首先将矩阵放入data.frame:
Q_hyda <- matrix(c(1950, 1950, 1950, 1951, 1951, 2014,
.265, .176, .873, .534, .142, .152),
ncol = 2)
df <- as.data.frame(Q_hyda)
names(df) <- c("year", "val")
# give them an ID within year
df$obs <- unlist(sapply(table(df$year), function(n) 1:n), use.names = FALSE)
df
# year val obs
# 1 1950 0.265 1
# 2 1950 0.176 2
# 3 1950 0.873 3
# 4 1951 0.534 1
# 5 1951 0.142 2
# 6 2014 0.152 1
现在我们申请reshape2:
require(reshape2)
dfm <- melt(df, id.vars = c("obs", "year"), value.name = "val")
dfc <- dcast(dfm, obs ~ year, mean, value.var = "val")
dfc
# obs 1950 1951 2014
# 1 1 0.265 0.534 0.152
# 2 2 0.176 0.142 NaN
# 3 3 0.873 NaN NaN
对于后续操作,这是一个比矩阵更好的对象类,但是如果你真的想要一个矩阵,你可以使用矩阵强制它:
mat_HQa <- as.matrix(dfc[, -1])
mat_HQa
# 1950 1951 2014
# [1,] 0.265 0.534 0.152
# [2,] 0.176 0.142 NaN
# [3,] 0.873 NaN NaN
答案 1 :(得分:1)
以下是使用'tidyr'软件包的解决方案:
> col1 <- rep(1950:2014, each = 59)
> col2 <- runif(length(col1))
> # add 'sample' as first column for the new row name
> Q_hyda <- data.frame(sample = 1:59, year = col1, value = col2)
> library(tidyr) # does it all for you
>
> new_data <- spread(Q_hyda, year, value)
>
> # small sample of data
> new_data[1:6, 1:4]
sample 1950 1951 1952
1 1 0.59867896 0.68813505 0.06603773
2 2 0.94072166 0.04474356 0.04468876
3 3 0.78878882 0.55344089 0.40102737
4 4 0.01339499 0.54489195 0.11938488
5 5 0.49914844 0.18922653 0.52316301
6 6 0.49786329 0.79751386 0.95561927
>
> View(new_data)
答案 2 :(得分:0)
补充数据。
col1 <- rep(1950:2014, each = 59)
col2 <- runif(length(col1))
Q_hyda <- cbind(col1, col2)
这有colnames,但它是一个矩阵。让我们试试建议的解决方案 为了。首先,@ ZheyuanLi
mat_HQa <- matrix(Q_hyda[, 2], ncol = 65); colnames(mat_HQa) <- 1950:2014
dim(mat_HQa)
## [1] 59 65
mat_HQa[1:5,1:3]
## 1950 1951 1952
## [1,] 0.5227552 0.3105570 0.33501591
## [2,] 0.4236526 0.7158999 0.04454956
## [3,] 0.8187411 0.1406177 0.02497711
## [4,] 0.5537462 0.6366948 0.92567469
## [5,] 0.2602161 0.7634615 0.85745645
这有效,虽然它假设你有相同的数字 每年观察。这很好,很直接,不需要转换 到data.frame。
接下来是@alexis_laz建议使用xtabs()
mat_HQa <- xtabs(Q_hyda[, 2] ~ seq_len(nrow(Q_hyda)) + Q_hyda[, 1])
dim(mat_HQa)
## [1] 3835 65
mat_HQa[1:5,1:3]
## Q_hyda[, 1]
## seq_len(nrow(Q_hyda)) 1950 1951 1952
## 1 0.5227552 0.0000000 0.0000000
## 2 0.4236526 0.0000000 0.0000000
## 3 0.8187411 0.0000000 0.0000000
## 4 0.5537462 0.0000000 0.0000000
## 5 0.2602161 0.0000000 0.0000000
这不是正确的答案。为了完成这项工作,我们需要第三个变量 它标识结果应该进入哪一行。
Q_hyda <- cbind(Q_hyda, rep(1:59, times = 65))
mat_HQa <- xtabs(Q_hyda[, 2] ~ Q_hyda[,3] + Q_hyda[, 1])
dim(mat_HQa)
## [1] 59 65
mat_HQa[1:5,1:3]
## Q_hyda[, 1]
## Q_hyda[, 3] 1950 1951 1952
## 1 0.52275520 0.31055703 0.33501591
## 2 0.42365262 0.71589995 0.04454956
## 3 0.81874106 0.14061770 0.02497711
## 4 0.55374618 0.63669482 0.92567469
## 5 0.26021608 0.76346147 0.85745645
这也是我们想要的,但现在它是继承自的类xtabs 表不是矩阵。我们可以将它强制回矩阵但必须记住 这样做!
mat_HQa <- as.matrix(mat_HQa)
mat_HQa[1:5, 1:3] # looks fine
## Q_hyda[, 1]
## Q_hyda[, 3] 1950 1951 1952
## 1 0.52275520 0.31055703 0.33501591
## 2 0.42365262 0.71589995 0.04454956
## 3 0.81874106 0.14061770 0.02497711
## 4 0.55374618 0.63669482 0.92567469
## 5 0.26021608 0.76346147 0.85745645
class(mat_HQa) # still not a matrix!
## [1] "xtabs" "table"
或许我们不能。所以对那个解决方案印象不深。可能没有矩阵 不用担心,但你永远不会知道。
一旦我们添加了额外的列,问题现在就来自于 this question,以及所有 一旦转换为data.frame,就会应用解决方案。那 包括使用@ Dave2e建议的reshape2或tidyr的答案。