【问题标题】:Using tidyverse to get raw_alpha values with the psych package from different datasets / databases使用 tidyverse 通过 psych 包从不同的数据集/数据库中获取 raw_alpha 值
【发布时间】:2019-04-20 18:50:50
【问题描述】:

我花了一天时间寻找这个答案,但我几乎要放弃了。实际上,我真的想象这是一个非常简单的情况,但我会很高兴得到任何帮助。

假设我有两个数据集,第一个获取所有学生的所有ID

library(tidyverse)
library(psych)

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

第二个有测试的所有结果。假设每一列都是一个 ID

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

现在我需要报告一个学生 ID 表,按学校分组,以及他们的结果(实际上,这是 Cronbach alpha 结果,这在心理学中很常见)。

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]

我尝试使用粘贴,noquotegsubstrcol

请运行此代码以获得可重现的结果。非常感谢!

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]

我想要的输出是这样的

为了给我的问题一些现实,那是真正的数据集,我必须在其中计算 Cronbach 的 alpha 项和每个组的项。

【问题讨论】:

  • 您能否也为这个示例提供您想要的结果?
  • 粘贴时,您正在创建一个字符向量。您不能将字符串“2,4”作为子集调用传递并期望得到与传递两个整数相同的结果。
  • @iod 请看一下新代码。我添加了一张图片并更改了代码以明确我的问题。谢谢。

标签: r tidyverse dplyr psych


【解决方案1】:
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 获得你的 alpha 值

  • 您使用$total 提取psych::alpha 给出的数据帧列表中的一个元素,但这在管道中不起作用(管道不处理列表,仅适用于数据帧)

所以基本上,psych::alpha 需要整个数据帧作为输入并输出数据帧列表,这与经典的dplyr 争论工作流不兼容。

【讨论】:

    【解决方案2】:

    我不确定这是否是您正在寻找的内容,但请尝试此操作并告诉我您是否获得了预期的结果。像这样替换您的 summarise 调用(还要注意 mutate 调用中的“unlist”):

    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 的 id。您需要将其与 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
    

    但这可能只是假数据本身的问题,而不是代码。

    【讨论】:

    • 谢谢,在我的真实数据集中,我得到了这个结果:k %&gt;% group_by(Fator) %&gt;% summarise(Qtde=n(), item = paste(item, collapse = ","), item = list(item), Min=round(min(Carga),2), Max=round(max(Carga),2)) %&gt;% mutate(item2=psych::alpha(items_a[unlist(item)])$total[1])Error in mutate_impl(.data, dots) : Evaluation error: Columns 9,15,16,17,18,19,20,21,22,23,24, 25, 1,12,13,30, 31,32,33, 2,3,4,5,6,7,10,11, 36,37,38, 28, 39,40,41`未找到。`
    • 所有这些列实际上都在items_a 中吗?你能给我names(items_a)的结果吗?
    • 当然,` items_a %>% names() [1] "i1" "i2" "i3" "i4" "i5" "i6" "i7" "i8" "i9" "i10 ""i11""i12""i13""i14""i15""i16""i17""i18""i19""i20"[21]"i21""i22""i23""i24""i25"" i26”“i27”“i28”“i29”“i30”“i31”“i32”“i33”“i34”“i35”“i36”“i37”“i38”“i39”“i40”[41]“i41”我更改了假代码以使其更易于理解。感谢您的帮助!
    • 我现在看到了问题-您的实际数据中的item 不是整数而是字符串,所以我们又遇到了同样的问题。在group_by(Fator) 之前插入此行,呼叫:mutate(item=lapply(strsplit(item,","),as.integer))。另外,从您的summarise 中删除item = paste(item, collapse = ",")
    • 非常感谢您的支持!!我会试试的,让你知道结果!! =) =)
    猜你喜欢
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-27
    • 2016-05-25
    • 1970-01-01
    • 2020-12-09
    相关资源
    最近更新 更多