如何在R中获得具有相同值的矩阵的所有托数

时间:2016-05-22 16:45:31

标签: r matrix

我有一个矩阵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,我无法弄清楚如何从第一列开始填充顶部。

我对编程非常陌生,因为它不是我的主题。 我怎样才能做到这一点?我确定认为这样做更容易。 我对任何建议深表感激。

3 个答案:

答案 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的答案。