如何使用从行名和列名计算的值填充R矩阵?

时间:2014-07-16 15:45:45

标签: r matrix

我有一个空的7乘7矩阵,但我希望它看起来像这样

    1   2   3   4   5   6   7
1   0   1   2   3   4   5   6
2   NA  0   1   2   3   4   5
3   NA  NA  0   1   2   3   4
4   NA  NA  NA  0   1   2   3
5   NA  NA  NA  NA  0   1   2
6   NA  NA  NA  NA  NA  0   1
7   NA  NA  NA  NA  NA  NA  0

我想知道如何填充它以便在列名称>时获取值行名称,从列名称中减去行名称,否则将其保留为NA

我还想知道如果它不是方阵,怎么做,行和列名称是日期,即

    26/03/2012  02/04/2012  09/04/2012  16/04/2012  23/04/2012  30/04/2012  07/05/2012  14/05/2012  21/05/2012  28/05/2012
26/03/2012  0   1   2   3   4   5   6   7   8   9
02/04/2012  NA  0   1   2   3   4   5   6   7   8
09/04/2012  NA  NA  0   1   2   3   4   5   6   7
16/04/2012  NA  NA  NA  0   1   2   3   4   5   6
23/04/2012  NA  NA  NA  NA  0   1   2   3   4   5
30/04/2012  NA  NA  NA  NA  NA  0   1   2   3   4
07/05/2012  NA  NA  NA  NA  NA  NA  0   1   2   3

3 个答案:

答案 0 :(得分:4)

如果你的矩阵是方形的,你可以使用这样的东西:

m <- matrix(0, nrow = 7, ncol = 7)                                               
m <- col(m) - row(m)                                                             
m[lower.tri(m)] <- NA                                                            

> m 
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    0    1    2    3    4    5    6
[2,]   NA    0    1    2    3    4    5
[3,]   NA   NA    0    1    2    3    4
[4,]   NA   NA   NA    0    1    2    3
[5,]   NA   NA   NA   NA    0    1    2
[6,]   NA   NA   NA   NA   NA    0    1
[7,]   NA   NA   NA   NA   NA   NA    0

答案 1 :(得分:4)

或者您可以使用outer

mat <- t(outer(1:7,1:7,"-"))
mat[lower.tri(mat)] <- NA

mat
     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    0    1    2    3    4    5    6
[2,]   NA    0    1    2    3    4    5
[3,]   NA   NA    0    1    2    3    4
[4,]   NA   NA   NA    0    1    2    3
[5,]   NA   NA   NA   NA    0    1    2
[6,]   NA   NA   NA   NA   NA    0    1
[7,]   NA   NA   NA   NA   NA   NA    0

这适用于其他类型的数据,例如日期:

library(lubridate)

dates <- ymd("2014-01-01") + dweeks(1:7)


mat <- t(outer(dates,dates,"-"))
mat[lower.tri(mat)] <- NA

mat
Time differences in secs
     [,1]   [,2]    [,3]    [,4]    [,5]    [,6]    [,7]
[1,]    0 604800 1209600 1814400 2419200 3024000 3628800
[2,]   NA      0  604800 1209600 1814400 2419200 3024000
[3,]   NA     NA       0  604800 1209600 1814400 2419200
[4,]   NA     NA      NA       0  604800 1209600 1814400
[5,]   NA     NA      NA      NA       0  604800 1209600
[6,]   NA     NA      NA      NA      NA       0  604800
[7,]   NA     NA      NA      NA      NA      NA       0

但是,通常最好将数据保存在data.frames中,而不是使用矩阵的行名和列名进行数学运算!例如:

one <- dmy(c("26/03/2012","02/04/2012","09/04/2012"))
two <- dmy(c("26/03/2012","02/04/2012"))

df <- expand.grid(one,two)


transform(df,diffdate = Var1 - Var2)

        Var1       Var2     diffdate
1 2012-03-26 2012-03-26       0 secs
2 2012-04-02 2012-03-26  604800 secs
3 2012-04-09 2012-03-26 1209600 secs
4 2012-03-26 2012-04-02 -604800 secs
5 2012-04-02 2012-04-02       0 secs
6 2012-04-09 2012-04-02  604800 secs

transform(df,diffdate = seconds_to_period(Var1 - Var2))

            Var1       Var2     diffdate
1 2012-03-26 2012-03-26           0S
2 2012-04-02 2012-03-26  7d 0H 0M 0S
3 2012-04-09 2012-03-26 14d 0H 0M 0S
4 2012-03-26 2012-04-02 -7d 0H 0M 0S
5 2012-04-02 2012-04-02           0S
6 2012-04-09 2012-04-02  7d 0H 0M 0S

答案 2 :(得分:0)

你可以这样做:

a <- matrix(nrows=7, ncols=7)
for (i in 1:7) {
   for (j in 1:7) {
        if (i>j) {
            a[i, j] <- NA
        } else  {
            a[i, j] <- j - i
        }
   }
}

如果没有两个for循环,我不知道是否有办法做到这一点。