Создать фрейм данных из вывода EFA в R

#r #psych #factor-analysis

#r #psych #факторный анализ

Вопрос:

Я работаю над EFA и хотел бы настроить свои таблицы. Существует функция, psych.print для подавления факторных загрузок определенного значения, чтобы таблицу было легче читать. Когда я запускаю эту функцию, она выдает эти данные и сводную статистику в консоли (в документе .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 как объект?

Комментарии:

1. Я не совсем уверен (поскольку вы не добавили воспроизводимые примеры), но попробуйте object_name <- as.table(print.psych(fa_ml_oblimin_2, cut=.32, sort=»TRUE»)).

Ответ №1:

Глядя на str объект, не похоже, что то, что вы хотите, встроено. Уродливым способом было бы использовать 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
  

Это возвращает :

 #            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
  

Комментарии:

1. Спасибо. Это отлично работает. Это помогло мне написать приведенную ниже функцию для создания более чистой таблицы данных результатов, хотя я не понял, как отсортировать ее наилучшим образом:

Ответ №2:

Ронак Шоу ответил на мой вопрос выше, и я использовал его ответ, чтобы помочь создать следующую функцию, которая почти воспроизводит psych.print data.frame fa.sort вывода

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