Использование tidyverse для получения значений raw_alpha с пакетом psych из разных наборов данных / баз данных - PullRequest
0 голосов
/ 18 ноября 2018

Я потратил один день в поисках этого ответа, и я почти сдался.На самом деле, я действительно представляю, что это довольно простая ситуация, но я буду рад любой помощи.

Допустим, У меня есть два набора данных , первый - получить все ID всех студентов

library(tidyverse)
library(psych)

ds_of_students <- data.frame(id=(1:4), school=c("public","private"))

Второй имеет все результаты теста.Допустим, каждый столбец является идентификатором .

ds_of_results <- structure(list(i1 = c(1, 2, 4, 4),
                                i2 = c(3, 3, 2, 2),
                                i3 = c(2, 3, 3, 5),
                                i4 = c(4, 1, 3, 2)), 
                           class = c("tbl_df", "tbl", 
                                     "data.frame"), row.names = c(NA, -4L))

А теперь мне нужно сообщить таблицу идентификаторов учащихся, сгруппированных по школам, и их результаты (На самом деле, это альфа-результаты Кронбаха, что довольно часто встречается в психологии).

ds_of_students %>%
  group_by(school) %>%
  summarise(n=n(), 
            id = paste(id, collapse = ",")) %>% 
  mutate(item2=psych::alpha(ds_of_results[c(id)])$total[1])

У меня есть это сообщение

Error in mutate_impl(.data, dots) : 
  Evaluation error: Columns `2,4`, `1,3` not found.

Но когда я бегу традиционным способом, это работает

psych::alpha(ds_of_results[c(1,3)])$total[1]

Я пытался работать с пастой, noquote , gsub ans strcol

Пожалуйста, запустите этот код, чтобы получить воспроизводимые результаты,Большое спасибо!

library(tidyverse)
library(psych)
ds_of_students <- data.frame(id=(1:4), school=c("public","private"))
ds_of_results <- structure(list(i1 = c(1, 2, 4, 4),
                                i2 = c(3, 3, 2, 2),
                                i3 = c(2, 3, 3, 5),
                                i4 = c(4, 1, 3, 2)), 
                           class = c("tbl_df", "tbl", 
                                     "data.frame"), row.names = c(NA, -4L))

ds_of_students %>%
  group_by(school) %>%
  summarise(n=n(), 
            id = paste(id, collapse = ",")) %>% 
  mutate(item2=psych::alpha(ds_of_results[c(id)])$total[1])


alpha(ds_of_results[c(1,3)])$total[1]

Мой желаемый результат - что-то вроде этого
Desired output

И просто чтобы дать некоторую реальность моему вопросу, это настоящийнабор данных, где я должен вычислить альфа-элемент Кронбаха для элементов каждой группы.

Real results

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018
get_alpha <- function(x) {  
  raw_alpha <-
    psych::alpha(
      ds_of_results[, ds_of_students[ds_of_students$school == x, 1]])$total[1]
  ids <-
    paste0(names(ds_of_results[, ds_of_students[ds_of_students$school == x, 1]]),
           collapse = ",")
  data.frame(
    school = x,
    id = ids,
    raw_alpha = raw_alpha
  )
}

map_df(levels(ds_of_students$school), get_alpha)

Результат

   school    id raw_alpha
1 private i2,i4      0.00
2  public i1,i3      0.85

В вашем коде было несколько проблем:

  • mutate использует переменные внутри фрейма данных, тогда как psych::alpha необходимоцелые кадры данных.Поэтому я не думаю, что вы можете получить свои альфа-значения с помощью mutate

  • , вы используете $total для извлечения одного элемента из списка фреймов данных, заданного psych::alpha, но этоне работает в конвейере (канал не обрабатывает списки и работает только с фреймами данных)

Таким образом, в основном, psych::alpha, который требует ввода целых фреймов данных и вывода спискафреймов данных не очень хорошо сочетается с классическим dplyr рабочим процессом.

0 голосов
/ 18 ноября 2018

Я не уверен, что это то, что вы ищете, но попробуйте это и скажите мне, если вы получите ожидаемый результат. Замените ваш summarise вызов следующим образом (также обратите внимание на «unlist» в вызове mutate):

ds_of_students %>% mutate(id=lapply(strsplit(id,","),as.integer))
    group_by(school) %>%
    summarise(id = list(id)) %>% 
mutate(item2=psych::alpha(ds_of_results[unlist(id)])$total[1])

То, что я здесь делаю, - это замена вашей вставки списком, чтобы номера оставались в виде чисел и могли быть переданы вызову подмножества на следующем шаге без помех. Это также будет работать, если id является символом, конечно, если предположить, что имена столбцов в ds_of_results являются идентификаторами из ds_of_students. Вам нужно передать его с unlist, чтобы подмножество получало его как простой вектор, а не как список с одним векторным элементом.

С вашими поддельными данными я получаю эту ошибку:

Some items ( i2 i4 ) were negatively correlated with the total scale and 
probably should be reversed.  
To do this, run the function again with the 'check.keys=TRUE' option# A tibble: 2 x 3
  school  id        item2       
  <fct>   <list>    <data.frame>
1 private <int [2]> -1          
2 public  <int [2]> -1          
Warning messages:
1: In cor.smooth(r) : Matrix was not positive definite, smoothing was done
2: In psych::alpha(ds_of_results[unlist(id)]) :
  Some items were negatively correlated with the total scale and probably 
should be reversed.  
To do this, run the function again with the 'check.keys=TRUE' option
3: In cor.smooth(R) : Matrix was not positive definite, smoothing was done
4: In cor.smooth(R) : Matrix was not positive definite, smoothing was done

Но это может быть проблемой только с поддельными данными, а не с кодом.

...