多个 ifelse 语句和 dplyr 管道,无法识别第二个对象

tal*_*ble 3 r dplyr

我想要做的是:从一个数据框中获取列,使用 ifelse 语句重新编码它们,然后将它们移动到一个新的数据框中,同时使用 dplyr 和管道一次性完成。

问题:该代码仅适用于一列,但一旦 R 在同一行代码中遇到多于一列,我就会遇到问题。第二列无法识别,R 抛出错误。我收到以下错误:

mutate_impl(.data, dots) 中的错误:评估错误:找不到对象“var2_orig”。

关于为什么会这样的任何想法?在不使用 ifelse 语句的情况下,可能还有一种更简单的方法。我也对这方面的建议持开放态度,但我仍然很好奇如何使用 ifelse 执行此操作以及为什么会出现不止一列的错误。非常感谢。

示例代码:

library(tidyverse)

# creating fake data set
df_orig <- data_frame(var1_orig = sample(1:3, 50, replace = T),
                  var2_orig = sample(-2:2, 50, replace = T))

# works for one var (recoding 3's as NA, 2's as 1, and 1's as 0):

df_new <- df_orig %>%
  as_tibble() %>%
  transmute(var1_new = ifelse(var1_orig == 3, NA, ifelse(var1_orig == 
  2, 1, ifelse(var1_orig == 1, 0, var1_orig))))

# and works the other var (recoding negatives as NA, 1's and 2's as 1, and 
leaving 0's as 0's):

df_new <- df_orig %>%
  as_tibble() %>%
  transmute(var2_new = ifelse(var2_orig < 0, NA, ifelse(var2_orig == 
  1 | var2_orig == 2, 1, 0)))

# but not together in same line of code (error: var2_orig not recognized):

df_new <- df_orig %>%
  as_tibble() %>%
  transmute(var1_new = ifelse(var1_orig == 3, NA, ifelse(var1_orig == 
  2, 1, ifelse(var1_orig == 1, 0, var1_orig)))) %>%
  transmute(var2_new = ifelse(var2_orig < 0, NA, ifelse(var2_orig == 
  1 | var2_orig == 2, 1, 0)))
Run Code Online (Sandbox Code Playgroud)

Sot*_*tos 5

Transmute 将删除变量,因此会出现错误。您可以使用mutate更新现有变量,然后rename_all(如果需要)更改它们的名称,

df_orig %>%
    as_tibble() %>%
    mutate(var1_orig = ifelse(var1_orig == 3, NA, ifelse(var1_orig == 2, 1,
                                                         ifelse(var1_orig == 1, 0, var1_orig))),
           var2_orig = ifelse(var2_orig < 0, NA, ifelse(var2_orig == 1 | var2_orig == 2, 1, 0))) %>%
    rename_all(funs(sub('_.*', '_new', .)))
Run Code Online (Sandbox Code Playgroud)


GGa*_*mba 5

dplyr 的动词transmute仅保留您创建的变量,并删除原始变量,因此var2_orig第二个transmute.

您可以在同一个transmute调用中创建两个变量,使用mutate,然后在不需要时删除原始变量。

顺便说一句,case_when在这里会很有用:

df_orig %>% 
  transmute(var1_new = case_when(var1_orig == 3 ~ NA_integer_,
                              var1_orig == 2 ~ 1L,
                              TRUE ~ var1_orig),
            var2_new = case_when(var2_orig < 0 ~ NA_integer_,
                              var2_orig %in% 1:2 ~ 1L,
                              TRUE ~ 0L)
  )
#> # A tibble: 50 x 2
#>    var1_new var2_new
#>       <int>    <int>
#>  1        1        1
#>  2        1        1
#>  3        1        0
#>  4       NA       NA
#>  5       NA        0
#>  6        1       NA
#>  7        1        1
#>  8        1        1
#>  9        1        1
#> 10        1        1
#> # ... with 40 more rows
Run Code Online (Sandbox Code Playgroud)