繁体   English   中英

在 R 中用 for 循环填充矩阵(计数和求和)

[英]Populating Matrix with for loop in R (count and sum)

我已经在这里问了一个相关的问题,可能没有充分说明,因此答案没有解决我的问题。 这次会努力做得更好。

我创建了 dataframe df

df <- data.frame(names1=c('mouse','dog','cat','cat','mouse','cat','cat','dog','cat','mouse'),                  names2=c('cat','dog','dog','mouse','cat','cat','mouse','mouse','mouse','mouse'),                  values=c(11,5,41,25,101,78,12,41,6,77))

names1names2列中都故意没有“鸟”。

和以下名称向量:

dims <- c('dog','mouse','bird','cat')

和一个最初为空的矩阵:

my_matrix <- matrix(data=0,nrow = length(unique(dims)),ncol = length(unique(dims))) rownames(my_matrix) <- c('dog','mouse','cat', 'bird') colnames(my_matrix) <- c('dog','mouse','cat','bird'))

所以空矩阵看起来像这样:

>        dog mouse bird cat
> dog     0     0    0   0
> mouse   0     0    0   0
> bird    0     0    0   0
> cat     0     0    0   0

**目标: **

目标是用来自 dataframe df的信息填充空矩阵

  1. 计数矩阵

在第一个矩阵中,我想计算向量元素匹配的次数。 所以第一个矩阵应该看起来和这个完全一样(基于df$names1 $names1 和df$names2

>        dog mouse bird cat
> dog     1     1    0   0
> mouse   0     1    0   2
> bird    0     0    0   0
> cat     1     3    0   1
  1. 求和矩阵

在第二个矩阵中,我想显示列df$values提供的总和,并基于df$names1 $names1 和df$names2给出的向量匹配元素。 所以矩阵应该看起来和这个一模一样

>        dog mouse bird cat
> dog     5     41    0   0
> mouse   0     77    0   112
> bird    0     0     0   0
> cat     0     137   0   25

限制:

关于矩阵的形状有一个限制——行和列的顺序由 dims 向量给出。 目的是矩阵应该显示df$names1 $names1 和df$names2中没有鸟

我的方法:

我尝试使用如下所示的 for 循环将计数和总和放入空矩阵的每个元素中:

for(i in 1:nrow(my_matrix)){
  for(j in 1:ncol(my_matrix)){
    my_matrix[i,j] <-  sum(df$values & df$names1[i] == df$names2[j] & df$names1[j] == df$names2[i])  
  }
}

这给了我这个不想要的结果

dog mouse bird cat
dog     0     0    0  10
mouse   0    10    0   0
bird    0     0    0   0
cat    10     0    0   0

我的直觉告诉我,使用 for 循环的方法是可以的,但我不确定如何准确地处理循环中的每个矩阵元素以及如何在总和 function 内定义限制以获得计数(目标矩阵 1)和总和(目标矩阵矩阵 2)。

非常感谢您的帮助,考虑到上述限制,我对其他解决方案持开放态度(仍然知道如何遍历矩阵并为每个 position 赋值会很酷)。

使用matchdata.table分组操作:

library(data.table)

n <- length(dims)
# initialize matrices
m_count <- m_sum <- matrix(0L, n, n, 0, list(dims, dims))

dt <- setDT(df)[
  , .(
    # the matrix index for the name1-name2 combination
    idx = (match(names2, dims) - 1L)*n + match(names1, dims),
    count = .N, # value for the count matrix
    sum = sum(values) # value for the sum matrix
  ),
  c("names1", "names2") # group by
]
# update matrices
m_count[dt$idx] <- dt$count
m_sum[dt$idx] <- dt$sum
m_count
#>       dog mouse bird cat
#> dog     1     1    0   0
#> mouse   0     1    0   2
#> bird    0     0    0   0
#> cat     1     3    0   1
m_sum
#>       dog mouse bird cat
#> dog     5    41    0   0
#> mouse   0    77    0 112
#> bird    0     0    0   0
#> cat    41    43    0  78

数据:

df <- data.frame(
  names1=c('mouse','dog','cat','cat','mouse','cat','cat','dog','cat','mouse'),
  names2=c('cat','dog','dog','mouse','cat','cat','mouse','mouse','mouse','mouse'),
  values=c(11,5,41,25,101,78,12,41,6,77)
)
dims <- unique(c('dog','mouse','bird','cat'))

继续您的 for 循环方法 - 您发布的代码仅循环遍历 dataframe 的前 4 个元素(例如矩阵的 nrow() 或 ncol() 的最大值),并且它与矩阵列的名称不匹配并且行到 dataframe 中的 names1 和 names2 向量。

我不确定以下内容是否正是您想要的,但它确实循环遍历了所有 dataframe,涉及 dataframe 和矩阵名称并计算/求和,因此您可以根据需要修改它。

my_matrix_count <- my_matrix

 for(i in 1:nrow(my_matrix)){

   for(j in 1:ncol(my_matrix)){

     my_matrix_count[i,j] <-  
       length(df$values[df$names1==row.names(my_matrix)[i] 
                & df$names2==colnames(my_matrix)[j] ]>0)

     my_matrix[i,j] <-  
       sum(df$values[df$names1==row.names(my_matrix)[i] 
                     & df$names2==colnames(my_matrix)[j] ])
  
     }
  }

在我看来,了解循环和索引是件好事,但是是的,它可以通过许多更好的方式来完成,例如 jblood94 的回答。 对于另一个版本,你也可以尝试这样写:

  xtabs(values ~names1 + names2, data=df)

问候,拉尔斯

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM