combine two looping structures to obtain a matrix output

怎甘沉沦 提交于 2021-02-18 08:38:49

问题


I'm using two closely related formulas in R. I was wondering if it might be possible to combine B1 and B2 to get my desired matrix output shown below?

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

desired matrix output:

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

回答1:


Maybe like this ?

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



回答2:


We could also do this in a single chain without having to redo the calculation. One of the advantages of using sum when compared to + in Reduce is that it can take into account the missing values with na.rm argument whereas if there are any NA while doing the +, it returns NA due to the property of 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


来源:https://stackoverflow.com/questions/66202448/combine-two-looping-structures-to-obtain-a-matrix-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!