从 R 中的 EFA 输出创建数据框

Create data frame from EFA output in R

我正在从事全民教育,想定制我的 table。有一个函数 psych.print 可以抑制某个值的因子载荷,使 table 更易于阅读。当我 运行 此函数时,它会在控制台中生成此数据和摘要统计信息(在 .RMD 文档中,它会生成控制台文本和单独的因子加载数据框,并抑制加载)。但是,如果我尝试将其保存为对象,它不会保留此数据。

这是一个例子:

library(psych)
bfi_data=bfi

bfi_data=bfi_data[complete.cases(bfi_data),]

bfi_cor <- cor(bfi_data)


factors_data <- fa(r = bfi_cor, nfactors = 6)
print.psych(fa_ml_oblimin_2, cut=.32, sort="TRUE")

在 R 脚本中,它产生这个:

          item   MR2   MR3   MR1   MR5   MR4   MR6    h2   u2 com
N2          17  0.83                               0.654 0.35 1.0
N1          16  0.82                               0.666 0.33 1.1
N3          18  0.69                               0.549 0.45 1.1
N5          20  0.47                               0.376 0.62 2.2
N4          19  0.44        0.43                   0.506 0.49 2.4
C4           9       -0.67                         0.555 0.45 1.3
C2           7        0.66                         0.475 0.53 1.4
C5          10       -0.56                         0.433 0.57 1.4
C3           8        0.56                         0.317 0.68 1.1
C1           6        0.54                         0.344 0.66 1.3

在 R Markdown 中,它会生成以下内容:

如何将 data.frame 保存为对象?

查看对象的 str 似乎不是您想要的 built-in。一种丑陋的方法是使用 capture.output 并尝试使用字符串操作将字符向量转换为数据帧。否则,由于正在显示数据,这意味着数据存在于对象本身的某处。我可以找到相同长度的向量,它们可以组合起来形成数据帧。

loadings <- unclass(factors_data$loadings)
h2 <- factors_data$communalities
#There is also factors_data$communality which has same values
u2 <- factors_data$uniquenesses
com <- factors_data$complexity
data <- cbind(loadings, h2, u2, com)
data

这个returns:

#            MR2   MR3   MR1   MR5   MR4   MR6   h2   u2  com
#A1         0.11  0.07 -0.07 -0.56 -0.01  0.35 0.38 0.62 1.85
#A2         0.03  0.09 -0.08  0.64  0.01 -0.06 0.47 0.53 1.09
#A3        -0.04  0.04 -0.10  0.60  0.07  0.16 0.51 0.49 1.26
#A4        -0.07  0.19 -0.07  0.41 -0.13  0.13 0.29 0.71 2.05
#A5        -0.17  0.01 -0.16  0.47  0.10  0.22 0.47 0.53 2.11
#C1         0.05  0.54  0.08 -0.02  0.19  0.05 0.34 0.66 1.32
#C2         0.09  0.66  0.17  0.06  0.08  0.16 0.47 0.53 1.36
#C3         0.00  0.56  0.07  0.07 -0.04  0.05 0.32 0.68 1.09
#C4         0.07 -0.67  0.10 -0.01  0.02  0.25 0.55 0.45 1.35
#C5         0.15 -0.56  0.17  0.02  0.10  0.01 0.43 0.57 1.41
#E1        -0.14  0.09  0.61 -0.14 -0.08  0.09 0.41 0.59 1.34
#E2         0.06 -0.03  0.68 -0.07 -0.08 -0.01 0.56 0.44 1.07
#E3         0.02  0.01 -0.32  0.17  0.38  0.28 0.51 0.49 3.28
#E4        -0.07  0.03 -0.49  0.25  0.00  0.31 0.56 0.44 2.26
#E5         0.16  0.27 -0.39  0.07  0.24  0.04 0.41 0.59 3.01
#N1         0.82 -0.01 -0.09 -0.09 -0.03  0.02 0.67 0.33 1.05
#N2         0.83  0.02 -0.07 -0.07  0.01 -0.07 0.65 0.35 1.04
#N3         0.69 -0.03  0.13  0.09  0.02  0.06 0.55 0.45 1.12
#N4         0.44 -0.14  0.43  0.09  0.10  0.01 0.51 0.49 2.41
#N5         0.47 -0.01  0.21  0.21 -0.17  0.09 0.38 0.62 2.23
#O1        -0.05  0.07 -0.01 -0.04  0.57  0.09 0.36 0.64 1.11
#O2         0.12 -0.09  0.01  0.12 -0.43  0.28 0.30 0.70 2.20
#O3         0.01  0.00 -0.10  0.05  0.65  0.04 0.48 0.52 1.06
#O4         0.10 -0.05  0.34  0.15  0.37 -0.04 0.24 0.76 2.55
#O5         0.04 -0.04 -0.02 -0.01 -0.50  0.30 0.33 0.67 1.67
#gender     0.20  0.09 -0.12  0.33 -0.21 -0.15 0.18 0.82 3.58
#education -0.03  0.01  0.05  0.11  0.12 -0.22 0.07 0.93 2.17
#age       -0.06  0.07 -0.02  0.16  0.03 -0.26 0.10 0.90 2.05

Ronak Shaw 回答了我上面的问题,我用他的回答帮助创建了以下函数,它几乎重现了 fa.sort 输出

psych.print data.frame
fa_table <- function(x, cut) {
  #get sorted loadings
  loadings <- fa.sort(fa_ml_oblimin)$loadings %>% round(3)
  #cut loadings
  loadings[loadings < cut] <- ""
  #get additional info
  add_info <- cbind(x$communalities, 
                    x$uniquenesses,
                    x$complexity) %>%
    as.data.frame() %>%
    rename("commonality" = V1,
           "uniqueness" = V2,
           "complexity" = V3) %>%
    rownames_to_column("item")
  #build table
  loadings %>%
    unclass() %>%
    as.data.frame() %>%
    rownames_to_column("item") %>%
    left_join(add_info) %>%
    mutate(across(where(is.numeric), round, 3))
}