【问题标题】:combine two looping structures to obtain a matrix output组合两个循环结构以获得矩阵输出
【发布时间】:2021-05-18 00:14:53
【问题描述】:

我在 R 中使用了两个密切相关的公式。我想知道是否可以结合 B1B2 来获得我的所需的矩阵输出,如下所示?

z <- "group    y1    y2
1 1         2     3
2 1         3     4
3 1         5     4
4 1         2     5
5 2         4     8
6 2         5     6
7 2         6     7
8 3         7     6
9 3         8     7
10 3        10     8
11 3         9     5
12 3         7     6"

dat <- read.table(text = z, header = T)

(B1 = Reduce("+", group_split(dat, group, .keep = FALSE) %>%
  map(~ nrow(.)*(colMeans(.)-colMeans(dat[-1]))^2)))

#     y1       y2 
#61.86667 19.05000

(B2 = Reduce("+",group_split(dat, group, .keep = FALSE) %>%
              map(~ nrow(.)*prod(colMeans(.)-colMeans(dat[-1])))))

# 24.4

想要的矩阵输出:

matrix(c(61.87,24.40,24.40,19.05),2)
#      [,1]  [,2]
#[1,] 61.87 24.40
#[2,] 24.40 19.05

【问题讨论】:

  • 这两个操作几乎相同。因此,您可以进行单个分组并获得输出。请检查以下解决方案。

标签: r dataframe matrix dplyr tidyverse


【解决方案1】:

可能是这样的?

mat <- matrix(B2, length(B1), length(B1))
diag(mat) <- B1
mat
#      [,1]  [,2]
#[1,] 61.87 24.40
#[2,] 24.40 19.05

【讨论】:

  • 你认为B1B2需要单独计算吗? (这就是问题)
  • @rnorouzian 您可以使用Reduce("+", group_split(dat, group, .keep = FALSE) %&gt;% map(~ {c(nrow(.)*(colMeans(.)-colMeans(dat[-1]))^2, nrow(.)*prod(colMeans(.)-colMeans(dat[-1])))})) 一起执行所有计算。但您仍然需要进行一些操作才能获得所需格式的输出。
【解决方案2】:

我们也可以在单个链中执行此操作,而无需重新计算。与Reduce 中的+ 相比,使用sum 的优点之一是它可以考虑na.rm 参数的缺失值,而如果在执行+ 时有任何NA,它会返回@ 987654326@由于NA的财产

library(dplyr)
dat %>% 
     # // group by group
     group_by(group) %>%
     # // create a count column 'n' 
     summarise(n = n(), 
      # // loop across y1, y2, get the difference between the grouped 
      # // column  mean value and the full data column mean
       across(c(y1, y2), ~ (mean(.) - mean(dat[[cur_column()]]))),
          .groups = 'drop') %>% 
      # // create the columns by multiplying the output of y1, y2 with n        
     transmute(y1y2 = y1 * y2 * n, 
            # //  Get the raised power of y1, y2, and multiply with n
           across(c(y1, y2), list(new1 = ~ n * .^2))) %>%
     # // then do a columnwise sum, replicate the 'y1y2' clumn
     summarise(across(everything(), sum, na.rm = TRUE), y1y2new = y1y2) %>% 
     # // rearrange the column order
     select(c(2, 1, 4, 3)) %>% 
     # // unlist to a vector
     unlist %>%
     # // create a matrix with 2 rows, 2 columns
     matrix(2, 2)
#         [,1]  [,2]
#[1,] 61.86667 24.40
#[2,] 24.40000 19.05

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-24
    • 1970-01-01
    • 2023-03-04
    • 2012-04-30
    • 1970-01-01
    相关资源
    最近更新 更多