简体   繁体   中英

Create data frame from EFA output in R

I am working on EFA and would like to customize my tables. There is a function, psych.print to suppress factor loadings of a certain value to make the table easier to read. When I run this function, it produces this data and the summary stats in the console (in an .RMD document, it produces console text and a separate data frame of the factor loadings with loadings suppressed). However, if I attempt to save this as an object, it does not keep this data.

Here is an example:

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")

In an R script, it produces this:

          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

In R Markdown, it produces this: 在此处输入图片说明

How can I save that data.frame as an object?

Looking at the str of the object it doesn't look that what you want is built-in. An ugly way would be to use capture.output and try to convert the character vector to dataframe using string manipulation. Else since the data is being displayed it means that the data is present somewhere in the object itself. I could find out vectors of same length which can be combined to form the dataframe.

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

This 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 answered my question above, and I used his answer to help create the following function, which nearly reproduces the psych.print data.frame of fa.sort output

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))
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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