[英]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))
names1
和names2
列中都故意没有“鸟”。
和以下名称向量:
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
的信息填充空矩阵
在第一个矩阵中,我想计算向量元素匹配的次数。 所以第一个矩阵应该看起来和这个完全一样(基于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
在第二个矩阵中,我想显示列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 赋值会很酷)。
使用match
和data.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.