对矩阵的所有列组合执行计算

时间:2019-05-25 15:29:08

标签: r for-loop matrix

我试图将一个函数应用于一个非常大的矩阵,我最终希望创建一个(40,000 by 40,000)矩阵(对角线的一侧仅完成)或创建结果列表。

矩阵如下:

            obs 1     obs 2     obs 3     obs 4     obs 5     obs 6     obs 7     obs 8     obs 9
words 1 0.2875775 0.5999890 0.2875775 0.5999890 0.2875775 0.5999890 0.2875775 0.5999890 0.2875775
words 2 0.7883051 0.3328235 0.7883051 0.3328235 0.7883051 0.3328235 0.7883051 0.3328235 0.7883051
words 3 0.4089769 0.4886130 0.4089769 0.4886130 0.4089769 0.4886130 0.4089769 0.4886130 0.4089769
words 4 0.8830174 0.9544738 0.8830174 0.9544738 0.8830174 0.9544738 0.8830174 0.9544738 0.8830174
words 5 0.9404673 0.4829024 0.9404673 0.4829024 0.9404673 0.4829024 0.9404673 0.4829024 0.9404673
words 6 0.0455565 0.8903502 0.0455565 0.8903502 0.0455565 0.8903502 0.0455565 0.8903502 0.0455565

我使用cosine(mat[, 3], mat[, 4])来给我一个数字。

          [,1]
[1,] 0.7546113

我可以对所有列进行此操作,但是我希望能够知道它们来自哪个列,即上面的计算来自34列,即{{1} }和"obs 3"

预期的输出可能是列表或类似矩阵的结果:

"obs 4"

(此处是组成数字的地方)

因此尺寸将是 [,1] [,1] [,1] [1,] 1 . . [1,] 0.75 1 . [1,] 0.23 0.87 1 ncol(mat)的大小(如果我使用矩阵方法)。

数据/代码:

ncol(mat)

其他

我考虑过要进行以下操作: -创建一个空矩阵并在forloop中计算该函数,但该函数无法按预期运行,并创建一个#generate some data mat <- matrix(data = runif(200), nrow = 100, ncol = 20, dimnames = list(paste("words", 1:100), paste("obs", 1:20))) mat #calculate the following function library(lsa) cosine(mat[, 3], mat[, 4]) cosine(mat[, 4], mat[, 5]) cosine(mat[, 5], mat[, 6]) 的0矩阵会引起内存问题。

40,000 by 40,000

我还尝试将结果放入列表中

co <- matrix(0L, nrow = ncol(mat), ncol = ncol(mat), dimnames = list(colnames(mat), colnames(mat)))
co

for (i in 2:ncol(mat)) {
  for (j in 1:(i - 1)) {
    co[i, j] = cosine(mat[, i], mat[, j])
  }
}

co

这也是错误的。

因此,我正在尝试创建一个函数,该函数将逐列计算该函数并存储结果。

4 个答案:

答案 0 :(得分:2)

一个选项是定义一个函数以应用于两列,然后使用// Class public class Department { public long Id { get; set; } public string DepartmentName { get; set; } } // IDepartment Manager public interface IDepartmentManager { Task<Department> CreateDepartment(Department entity); Task Update(Department entity); Task Delete(long id); Task<IEnumerable<Department>> GetAll(); } // Department Manager private readonly IRepository<Department, long> _departmentRepo; public DepartmentManager(IRepository<Department, long> departmentRepo) { _departmentRepo = departmentRepo } 应用于所有列组合。

outer

答案 1 :(得分:2)

1)使用问题中显示的public static async importOrganizations(body){ let connection = getConnection(); let objs = {}; // Line to delete -> connection.getRepository(Organization); let o = await connection.getRepository(Organization).save(this.createObjects(body, objs)); } ,第一行创建一个20x20矩阵,其中所有20 * 20余弦均被填充。第二行将0和x上的值归零。对角线。如果您希望对角线上下的值都为零,请使用mat

lower.tri

2)交替创建结果的命名数值向量:

comat <- cosine(mat)
comat[upper.tri(comat, diag = TRUE)] <- 0

3)我们可以使用这样一个事实,即对角余弦与相关系数最高为covec <- c(combn(as.data.frame(mat), 2, function(x) c(cosine(x[, 1], x[, 2])))) names(covec) <- combn(colnames(mat), 2, paste, collapse = "-")

mult

3a)使用R中可用的多个相关函数中的任何一个打开。例如,使用刚刚计算的mult <- c(cosine(mat[, 1], mat[, 2]) / cor(mat[, 1], mat[, 2])) co3 <- mult * cor(mat) co3[upper.tri(co3, diag = TRUE)] <- 0

mult

3b)

library(HiClimR)
co4 <- mult * fastCor(mat)
co4[upper.tri(co4, diag = TRUE)] <- 0

3c)

library(propagate)
co5 <- mult * bigcor(mat)
co5[upper.tri(co5, diag = TRUE)] <- 0

答案 2 :(得分:1)

我们可以使用嵌套的sapply

i1 <- seq_len(ncol(mat))
sapply(i1, function(i) sapply(i1, function(j) cosine(mat[, i], mat[, j])))    #         [,1]      [,2]      [,3]      [,4]      [,5]      [,6]      [,7]      #[,8]      [,9]     [,10]     [,11]     [,12]
# [1,] 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016
# [2,] 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000
# [3,] 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016
# [4,] 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000
# [5,] 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016
# [6,] 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000
# [7,] 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016 1.0000000 0.7849016
# ....

答案 3 :(得分:0)

我们可以使用purrr对索引进行迭代(作为for循环的更好(?)替代方法)。我认为玩具数据集应该有2000个数据点,而不是200个数据点?

library(tidyverse)

mat <-
  matrix(
    data = runif(2000),
    nrow = 100,
    ncol = 20,
    dimnames = list(paste("words", 1:100),
                    paste("obs", 1:20))
  )

cos_summary <- tibble(Row1 = 3:5, Row2 = 4:6)

cos_summary <- cos_summary %>%
  mutate(cos_1_2 = map2_dbl(Row1, Row2, ~lsa::cosine(mat[,.x], mat[,.y])))

cos_summary

# A tibble: 3 x 3
   Row1  Row2 cos_1_2
  <int> <int>   <dbl>
1     3     4   0.710
2     4     5   0.734
3     5     6   0.751