为矩阵创建行和列

时间:2019-02-20 21:04:14

标签: r

我有一个矩阵。这些行是所有者(a,b,c ...);列是公司(c1,c2,...)。示例数据如下:

m1 <- matrix(0.1, nrow = 3, ncol = 3, dimnames = list(c('a','b','c'), c('c1','c2','c3')))

m1显示所有者a,b,c,每个拥有的公司c1,c2,c3 10%。我想创建一些假设所有者,以便每个假设所有者拥有一个公司的剩余70%的股份,但不拥有其他公司。所需的输出如下。在期望的输出中,d,e,f是假设所有者,每个所有者拥有一家公司的70%。

    c1  c2  c3
a   0.1 0.1 0.1
b   0.1 0.1 0.1
c   0.1 0.1 0.1
d   0.7 NA  NA
e   NA  0.7 NA
f   NA  NA  0.7

我可以像下面这样手动操作,但是我想知道如何务实地做到这一点。请注意,在某些情况下,所有者或公司超过三个,并且所有权不等于0.1。新所有者的数量将与公司的数量相同,因为每个新所有者仅拥有一个公司。

d <- c(0.7, NA, NA)
m2 <- rbind(m1, d)

3 个答案:

答案 0 :(得分:2)

这应该可以完成工作。

首先,创建一个对角矩阵m2,对角线的每个元素都是1与矩阵m1之和之间的差

m1 <- matrix(0.1, nrow = 3, ncol = 3, dimnames = list(c('a','b','c'), c('c1','c2','c3')))

m2 <- diag(1 - colSums(m1))

m2
#>      [,1] [,2] [,3]
#> [1,]  0.7  0.0  0.0
#> [2,]  0.0  0.7  0.0
#> [3,]  0.0  0.0  0.7

然后,我们需要将行名添加到m2。我们可能要分配用于m1的字母 not 的前3个字母。这样做的好处是您无需指定新矩阵的行名-它们将根据尚未使用的行进行分配。

rownames(m2) <- letters[!letters %in% rownames(m1)][1:nrow(m2)]

rbind(m1, m2)
#>    c1  c2  c3
#> a 0.1 0.1 0.1
#> b 0.1 0.1 0.1
#> c 0.1 0.1 0.1
#> d 0.7 0.0 0.0
#> e 0.0 0.7 0.0
#> f 0.0 0.0 0.7

如您所见,此代码仍可用于m1中更多的行/列和不同的数字:

m1 <- matrix(0.11, nrow = 3, ncol = 4, dimnames = list(c('a','b','c'), c('c1','c2','c3','c4')))

m1
#>     c1   c2   c3   c4
#> a 0.11 0.11 0.11 0.11
#> b 0.11 0.11 0.11 0.11
#> c 0.11 0.11 0.11 0.11

m2 <- diag(1 - colSums(m1))

m2
#>      [,1] [,2] [,3] [,4]
#> [1,] 0.67 0.00 0.00 0.00
#> [2,] 0.00 0.67 0.00 0.00
#> [3,] 0.00 0.00 0.67 0.00
#> [4,] 0.00 0.00 0.00 0.67

rownames(m2) <- letters[!letters %in% rownames(m1)][1:nrow(m2)]

rbind(m1, m2)
#>     c1   c2   c3   c4
#> a 0.11 0.11 0.11 0.11
#> b 0.11 0.11 0.11 0.11
#> c 0.11 0.11 0.11 0.11
#> d 0.67 0.00 0.00 0.00
#> e 0.00 0.67 0.00 0.00
#> f 0.00 0.00 0.67 0.00
#> g 0.00 0.00 0.00 0.67

reprex package(v0.2.1)于2019-02-20创建

答案 1 :(得分:0)

m2 = rbind(m1, do.call(rbind, lapply(1:NCOL(m1), function(i) replace(rep(NA, NCOL(m1)), i, 0.7))))
row.names(m2) = c(row.names(m1), c("d", "e", "f"))
m2
#   c1  c2  c3
#a 0.1 0.1 0.1
#b 0.1 0.1 0.1
#c 0.1 0.1 0.1
#d 0.7  NA  NA
#e  NA 0.7  NA
#f  NA  NA 0.7

答案 2 :(得分:0)

我们可以使用matrix元素来设置创建NA,并用百分比填充对角线。正如@Jilber Urbina指出的那样,我们可以在row.names中声明matrix

hypo_companies <- c("d", "e", "f")
percentage <- 0.7

hypo_len <- length(hypo_companies)
hypo_mat <- matrix(NA, hypo_len, hypo_len, dimnames = list(hypo_companies))
diag(hypo_mat) <- rep(percentage, hypo_len)
rbind(m1, hypo_mat)

输出:

   c1  c2  c3
a 0.1 0.1 0.1
b 0.1 0.1 0.1
c 0.1 0.1 0.1
d 0.7  NA  NA
e  NA 0.7  NA
f  NA  NA 0.7