当mutate_all和lapply不一致时...如何用mutate_all替换lapply

时间:2019-02-14 21:10:36

标签: r dplyr lapply tidyverse

我再次在这里寻求您的帮助! 我试图弄清楚mutate_all(或我...)发生了什么。

假设我有这个数据集:

ds <- structure(list(Q1 = structure(c(5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 
                                      5, 4, 3, 5, 5, 5, 5, 5, 1, 4, 5, 5, 3, 4, 5, 5, 5, 5, 5, 2, 5, 
                                      5, 4, 5, 5, 3, 5, 5, 4, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 
                                      5, 4), label = "1 Para mim é igual se os meus amigos são heterossexuais ou homossexuais.", format.spss = "F1.0", display_width = 3L, class = "labelled", labels = c(`discordo totalmente` = 1, 
                                                                                                                                                                                                          discordo = 2, indiferente = 3, concordo = 4, `concordo totalmente` = 5
                                      )), Q2 = structure(c(1, 1, 1, 1, 1, 1, 3, 1, 2, 3, 1, 4, 4, 4, 
                                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 
                                                           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2), label = "A homossexualidade é uma perturbação psicológica/biológica.", format.spss = "F1.0", display_width = 5L, class = "labelled", labels = c(`discordo totalmente` = 1, 
                                                                                                                                                                                                                                                                     discordo = 2, indiferente = 3, concordo = 4, `concordo totalmente` = 5
                                                           )), Q3 = structure(c(5, 2, 5, 4, 5, 4, 5, 5, 5, 4, 5, 5, 2, 3, 
                                                                                5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 
                                                                                5, 5, 5, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 5, 4, 5, 4), label = "Acredito que os pais e as mães homossexuais são tão competentes como os pais e mães heterossexuais.", format.spss = "F1.0", display_width = 5L, class = "labelled", labels = c(`discordo totalmente` = 1, 
                                                                                                                                                                                                                                                                                                                                  discordo = 2, indiferente = 3, concordo = 4, `concordo totalmente` = 5
                                                                                )), Q4 = structure(c(1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 
                                                                                                     1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 2, 
                                                                                                     1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 5, 1, 1, 2, 1, 3), label = "4 Todas as Lésbicas, Gays, Bissexuais, Transexuais, Transgêneros e Intersexuais (LGBTI) me deixam irritado.", format.spss = "F1.0", display_width = 4L, class = "labelled", labels = c(`discordo totalmente` = 1, 
                                                                                                                                                                                                                                                                                                                                                               discordo = 2, indiferente = 3, concordo = 4, `concordo totalmente` = 5
                                                                                                     )), Q5 = structure(c(1, 4, 1, 1, 1, 1, 3, 1, 2, 1, 1, 1, 3, 3, 
                                                                                                                          1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 2, 
                                                                                                                          1, 1, 1, 2, 2, 5, 1, 4, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3), label = "A legalização do casamento entre pessoas do mesmo sexo é muito errada.", format.spss = "F1.0", display_width = 5L, class = "labelled", labels = c(`discordo totalmente` = 1, 
                                                                                                                                                                                                                                                                                                                                               discordo = 2, indiferente = 3, concordo = 4, `concordo totalmente` = 5
                                                                                                                          ))), row.names = c(NA, -54L), class = c("tbl_df", "tbl", "data.frame"
                                                                                                                          ))

然后我需要将所有变量转换为 factors 进行绘制。我真的很喜欢dplyr的方法:

ds_mutate <- ds %>% mutate_all(., factor, levels=1:5)
likert(ds_mutate)

但是出现此错误:

Error in likert(ds_mutate) : 
  All items (columns) must have the same number of levels

STR mutate all

当我使用lapply时(没人会相信我的“ apply”功能很直观...),效果很好:

> ds_apply <- lapply(ds, factor, levels=1:5) %>% as.data.frame()
> likert(ds_apply)
  Item         1         2         3         4         5
1   Q1  1.851852  1.851852  9.259259 14.814815 72.222222
2   Q2 77.777778  9.259259  5.555556  7.407407  0.000000
3   Q3  0.000000  3.703704  1.851852 14.814815 79.629630
4   Q4 79.629630 14.814815  3.703704  0.000000  1.851852
5   Q5 72.222222  7.407407 14.814815  3.703704  1.851852

但是正如您所看到的,str对我而言是相同的... STR APPLY

我期待着您的回音!

谢谢!

2 个答案:

答案 0 :(得分:3)

有一个区别:

class(ds_mutate)
# [1] "tbl_df"     "tbl"        "data.frame"
class(ds_apply)
# [1] "data.frame"

然后问题出在以下事实中:在likert的召唤中,我们拥有

nlevels = length(levels(items[, 1]))

在前一种情况下,

length(levels(ds_mutate[, 1]))
# [1] 0

因为

ds_mutate[, 1]
# A tibble: 54 x 1
#    Q1   
#    <fct>
#  1 5    
#  2 4    
#  3 5    
#  4 5    
#  5 5    
#  6 5    
#  7 5    
#  8 5    
#  9 5    
# 10 5    
# … with 44 more rows

,即结果是小标题。还有,

methods("levels")
# [1] levels.default

,这样就没有levels的小方法了。还要注意

class(ds_mutate) <- c("data.frame", "tbl_df", "tbl")
ds_mutate[, 1]
#  [1] 5 4 5 5 5 5 5 5 5 5 5 4 3 5 5 5 5 5 1 4 5 5 3 4 5 5 5 5 5 2 5 5 4 5 5 3 5 5 4 3 3 5 5 5
# [45] 5 5 5 5 5 5 5 4 5 4
# Levels: 1 2 3 4 5

在这种情况下

likert(ds_mutate)

也开始工作。在不修改类的情况下,您也可以使用

likert(data.frame(ds_mutate))

其他

中的lapply
lapply(ds, factor, levels = 1:5)
一旦我们了解一件事,

实际上是非常直观的:数据框是列表的一种特例,其中每个列表元素的长度相同。知道sapplylapply的工作方式是它遍历第一个参数的每个元素:一旦我们将ds视为一个数据帧,其元素(因为它是一个列表)是列,很清楚它是如何工作的。出于相同的原因,由于在这种情况下factor的结果具有相同的长度,因此可以将调用lapply产生的列表很好地转换为数据帧。

答案 1 :(得分:2)

我从没使用过likert包,但是看起来它并没有像tibble这样的对象。这对我有用:

likert(as.data.frame(ds_mutate))