使用 R 在数据框中重新编码多个变量的最短、最干净的方法是什么?

2fr*_*eet 2 r dplyr recode

所以我在社会科学领域工作,我经常要做的就是操纵多个变量来改变价值观。通常这意味着扭转规模。我使用SPSS已经很长时间了,它的语法非常简单。要更改多个变量的值,请编写:

RECODE var1 var2 var3 (1=5) (2=4) 4=2) (5=1) (ELSE=COPY).

into newvar1 newvar1 newvar3.要在最后添加的新变量中编写新代码。在括号中,您可以使用hilo1 to 4等内容。

现在我正在努力学习R,并且正在努力寻找完成类似工作流程的最佳方法。我找到了以下解决方案,但找不到一个简短的好方法:

## Packages -----
library(dplyr)
library(car)

## Data -----
tib <- tibble(v1 = 1:4, 
              v2 = 1:4,
              v3 = sample(1:5, 4, replace = FALSE))

vars <- c("v1", "v2", "v3")

Run Code Online (Sandbox Code Playgroud)

基本方式:

tib$v2_rec <- NA
tib$v2_rec[tib$v2 == 1] <- 5 #1
tib$v2_rec[tib$v2 == 2] <- 4 #2
tib$v2_rec[tib$v2 == 3] <- 3 #3
tib$v2_rec[tib$v2 == 4] <- 2 #4
tib$v2_rec[tib$v2 == 5] <- 1 #5
# I'm forced to create a new variable here, otherwise #4 and #5 overwrite #1 and #2.
# Therefore I won't even bother to try to loop trough multiple variables.
Run Code Online (Sandbox Code Playgroud)

来自包 car 的 recode() :

tib$v1 <- recode(tib$v1, "1=5; 2=4; 4=2; 5=1")
# This is nice, understandable and short
# To handle multiple variables the following solutions won't work, because the reload functions seems not to be able to iterate through lists:

tib[vars] <- recode(tib[vars], "1=5; 2=4; 4=2; 5=1")
tib[1:3] <- recode(tib[1:3], "1=5; 2=4; 4=2; 5=1")

# I'd be forced to loop:

for (i in vars) {
  tib[[i]] <- recode(tib[[i]], "1=5; 2=4; 4=2; 5=1")
}
Run Code Online (Sandbox Code Playgroud)

我对此非常满意,但我想知道是否有一个函数可以为我完成循环工作。我现在真的很挣扎于 dplyer 功能,我很不高兴我无法直观地弄清楚事情......

我尝试变异:

#I get it for a single case and for multiple cases i got to a solution in combination with the recode() function:

tib <- tib %>%
  mutate_at(vars(v1:v3), 
            function(x) recode(x, "1=5; 2=4; 4=2; 5=1"))

Run Code Online (Sandbox Code Playgroud)

这是最好的方法吗?需要明确的是,我看到了一些使用 case_when()、replace() 或 mapvalues() 的其他解决方案,但我发现上面的解决方案更好,因为我喜欢看看什么值被重新编码为什么值。

我对 apply() 函数有了一些了解,甚至无法用它重新编码一个变量。我确信我很快就会掌握这一点,但目前我只是有点沮丧,因为我在 SPSS 中花了很长时间寻找工作流程。如果您知道比上面使用 apply() 函数更短、更清晰的解决方案,我将不胜感激!

我对 R 及其可能性感到满意,但现在我需要正确方向的提示来让我继续前进!先感谢您!

JBG*_*ber 5

我认为如果使用正确,dplyr在这种情况下具有“最干净”的语法:

library(dplyr)
tib <- tibble(v1 = 1:4, 
              v2 = 1:4,
              v3 = sample(1:5, 4, replace = FALSE))

tib %>% 
  mutate_at(vars(v1:v3), recode, `1` = 5, `2` = 4, `3` = 3, `4` = 2, `5` = 1)
#> # A tibble: 4 x 3
#>      v1    v2    v3
#>   <dbl> <dbl> <dbl>
#> 1     5     5     2
#> 2     4     4     5
#> 3     3     3     4
#> 4     2     2     1
Run Code Online (Sandbox Code Playgroud)

请注意,我必须添加3 = 3,因为重新编码需要替换所有值。

我经常发现使用对我来说新的函数更明确地编写东西更容易,所以也许这可能会有所帮助:

tib %>% 
  mutate_at(.vars = vars(v1:v3), 
            .funs = function(x) recode(x, 
                                       `1` = 5, 
                                       `2` = 4, 
                                       `3` = 3, 
                                       `4` = 2, 
                                       `5` = 1))
Run Code Online (Sandbox Code Playgroud)

如果您更喜欢该recode功能,car则不应加载car而应使用:

tib %>% 
  mutate_at(vars(v1:v3), car::recode, "1=5; 2=4; 4=2; 5=1")
Run Code Online (Sandbox Code Playgroud)

这样你就不会在混合时遇到麻烦dplyr(car只要你不需要car任何其他东西。