使用 mutate、cross、case_when 将多个变量设置为 NA 的类型冲突

Eli*_*eth 4 r typeerror na dplyr

我想使用mutateacross和的组合来跨多个变量case_when将某些情况设置为NA(缺失)。

\n

假设我有一个指示变量“vs”,标记应该用于NA变量“carb”和“gear”的情况。我想使用类似的方法将这些情况同时设置为缺少这两个变量:

\n
data(mtcars) #load mtcars data\nmtcars$carb <- as.integer(mtcars$carb) #set to integer,\n                                       #for purposes of illustration\n\nmtcars <- mtcars %>%\n  mutate(across(c(gear:carb), ~ case_when(vs==1~NA,\n                                      T~.)))\n
Run Code Online (Sandbox Code Playgroud)\n

我希望将“gear”和“carb”更改为NA“vs”等于 1 的所有情况。但是,由于 carb 是整数而 gear 是数字,所以我遇到了类型冲突:

\n
Error: Problem with `mutate()` input `..1`.\n\xe2\x84\xb9 `..1 = across(c(gear:carb), ~case_when(vs == 1 ~ NA, T ~ .))`.\nx must be a logical vector, not a double vector.\n
Run Code Online (Sandbox Code Playgroud)\n

如果我单独使用mutate每个变量,我将替换NANA_integer_“碳水化合物”和“NA齿轮NA_real_”。我在这里不能这样做,因为变量包含不同类型的数据。

\n

有什么办法可以解决这个问题,或者我只能mutate(across())像这样使用相同类型的变量吗?

\n

谢谢你!

\n

ste*_*fan 6

另一种选择是使用if语句:

library(dplyr)

mtcars$carb <- as.integer(mtcars$carb)

mtcars <- mtcars %>%
  mutate(across(c(gear:carb), ~ case_when(
    vs == 1 ~ if (is.integer(.)) NA_integer_ else NA_real_,
    T ~ .
  )))
Run Code Online (Sandbox Code Playgroud)

但由于 @r2evans 的评论,我学到的更聪明的方法是使用.[NA]“总是给出适当的NA类型”:

mtcars <- mtcars %>%
  mutate(across(c(gear:carb), ~ case_when(
    vs == 1 ~ .[NA],
    T ~ .
  )))

head(mtcars)
#>                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
#> Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#> Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1   NA   NA
#> Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0   NA   NA
#> Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
#> Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0   NA   NA
Run Code Online (Sandbox Code Playgroud)

  • 快捷方式:`vs == 1 ~ .[NA]`将始终在类敏感函数(如`if_else`和`case_when`)中给出适当的`NA`类型。(有时我需要使用 `.[NA][1]`。)它只是快一点点,但我认为代码高尔夫比 `if (is.integer(.) )` 以及函数堆栈开销。 (3认同)
  • @r2evans 关于“我不认为`.[NA]`是正式的东西”:因为**索引中的NA**在`?Extract`中描述 - “提取时,数字,逻辑或字符`NA` index 选择一个未知元素,因此在逻辑、整数、数字、复数或字符结果的相应元素中返回“NA”——我认为它相当正式。如果我理解正确的话;)可以在[此处](/sf/answers/4231948941/)找到类似设置中的另一种“强制方法”。干杯 (2认同)