如何简化转换多个列属性并重新编码多个列?

How to simplify converting several column attributes and recoding multiple columns?

我有几行代码正在研究如何简化。我这样做的尝试导致了错误。下面是一小部分代码行:

SS_data$Cope1 <- as.numeric(SS_data$Cope1)
SS_data$Cope2 <- as.numeric(SS_data$Cope2)
SS_data$Cope3 <- as.numeric(SS_data$Cope3)
SS_data$Cope4 <- as.numeric(SS_data$Cope4)
SS_data$Cope5 <- as.numeric(SS_data$Cope5)
SS_data$Cope6 <- as.numeric(SS_data$Cope6)
SS_data$Cope7 <- as.numeric(SS_data$Cope7)
SS_data$Cope8 <- as.numeric(SS_data$Cope8)
SS_data$Cope9 <- as.numeric(SS_data$Cope9)
SS_data$Cope10 <- as.numeric(SS_data$Cope10)
SS_data$Cope11 <- as.numeric(SS_data$Cope11)
SS_data$Cope12 <- as.numeric(SS_data$Cope12)
SS_data$Cope13 <- as.numeric(SS_data$Cope13)
SS_data$Cope14 <- as.numeric(SS_data$Cope14)
SS_data$Cope15 <- as.numeric(SS_data$Cope15)
SS_data$Cope16 <- as.numeric(SS_data$Cope16)
SS_data$Cope17 <- as.numeric(SS_data$Cope17)
SS_data$Cope18 <- as.numeric(SS_data$Cope18)
SS_data$Cope19 <- as.numeric(SS_data$Cope19)
SS_data$Cope20 <- as.numeric(SS_data$Cope20)

我也在尝试简化下面的代码。我最终为每个变量重新编码,我想知道是否也有一种方法可以简化它。

WHOQOL16[WHOQOL16 == "Very dissatisfied"] <- 1
WHOQOL16[WHOQOL16 == "Dissatisfied"] <- 2
WHOQOL16[WHOQOL16 == "Neither satisfied nor dissatisfied"] <- 3
WHOQOL16[WHOQOL16 == "Satisfied"] <- 4
WHOQOL16[WHOQOL16 == "Very satisfied"] <- 5
              
WHOQOL17[WHOQOL17 == "Very dissatisfied"] <- 1
WHOQOL17[WHOQOL17 == "Dissatisfied"] <- 2
WHOQOL17[WHOQOL17 == "Neither satisfied nor dissatisfied"] <- 3
WHOQOL17[WHOQOL17 == "Satisfied"] <- 4
WHOQOL17[WHOQOL17 == "Very satisfied"] <- 5
              
WHOQOL18[WHOQOL18 == "Very dissatisfied"] <- 1
WHOQOL18[WHOQOL18 == "Dissatisfied"] <- 2
WHOQOL18[WHOQOL18 == "Neither satisfied nor dissatisfied"] <- 3
WHOQOL18[WHOQOL18 == "Satisfied"] <- 4
WHOQOL18[WHOQOL18 == "Very satisfied"] <- 5
              
WHOQOL19[WHOQOL19 == "Very dissatisfied"] <- 1
WHOQOL19[WHOQOL19 == "Dissatisfied"] <- 2
WHOQOL19[WHOQOL19 == "Neither satisfied nor dissatisfied"] <- 3
WHOQOL19[WHOQOL19 == "Satisfied"] <- 4
WHOQOL19[WHOQOL19 == "Very satisfied"] <- 5

发布到 SO 上 标签的问题应该包括可重现的数据,但我已经这样做了 你这次在备注最后。

以下仅使用base R.

首先在 DF2 中复制 DF 以防你想从头开始再次 运行 代码,因为代码将覆盖 DF2.

接下来将第 1 列和第 2 列转换为数字,并将第 3 列和第 4 列中的 X、Y 和 Z 转换为第 1、2 和 3 列。如果 non-numeric 个条目出现在第 1 或第 2 列中,或者条目不是X、Y 或 Z 出现在第 3 或 4 列中,然后 NA 将分配给这些条目。 (或者,对于第二行代码, dplyr 包中存在一个 recode 函数,而 car 包中存在一个具有相同目的的不同 recode 函数。)

列号在此示例中很明显,但如果它们不在您的数据中,请使用 grep("Cope", names(DF)) 等表达式来获取它们。

DF2 <- DF
DF2[1:2] <- lapply(DF2[1:2], as.numeric)
DF2[3:4] <- lapply(DF2[3:4], match, c("X", "Y", "Z"))

给出以下警告只是为了让您知道它遇到了一个无法转换为数字的值,因此将其转换为 NA。

> DF2
Warning message:
In lapply(DF[1:2], as.numeric) : NAs introduced by coercion
   A  B  C  D
1  1 11  1  1
2 NA 12  2 NA
3  3 13 NA  3

备注

DF <- data.frame(A = c("1", "x", "3"), B = c("11", "12", "13"),
  C = c("X", "Y", "a"), D = c("X", NA, "Z"))

dplyr 中,您可以使用 across 函数将相同的函数应用于多个列。

我们将以 "Cope" 开头的列更改为数字,并对以 "WHOQOL" 开头的列重新编码。

library(dplyr)

SS_data_new <- SS_data %>% 
                    mutate(across(starts_with('Cope'), as.numeric), 
                           across(starts_with('WHOQOL'), 
                           ~recode(., "Very dissatisfied" = 1, 
                                       "Dissatisfied" = 2, 
                                       "Neither satisfied nor dissatisfied" = 3, 
                                       "Satisfied" = 4, 
                                       "Very satisfied" = 5)))
SS_data_new
#  Cope1 Cope2 WHOQOL
#1     1     4      1
#2     2     5      1
#3     3     6      4
str(SS_data_new)
#data.frame':   3 obs. of  3 variables:
# $ Cope1 : num  1 2 3
# $ Cope2 : num  4 5 6
# $ WHOQOL: num  1 1 4

数据

SS_data <- data.frame(Cope1 = c('1', '2', '3'), Cope2 = c('4', '5', '6'), 
           WHOQOL = c("Very dissatisfied", "Very dissatisfied", "Satisfied"))