【问题标题】:Type conflict setting multiple variables to NA with mutate, across, case_when使用 mutate、cross、case_when 将多个变量设置为 NA 的类型冲突
【发布时间】:2022-01-11 06:46:14
【问题描述】:

我想使用mutateacrosscase_when 的组合在多个变量中将某些情况设置为NA(缺失)。

假设我有一个指示变量“vs”标记案例,对于变量“carb”和“gear”应该是 NA。我想使用这样的东西来将这些情况设置为同时丢失这两个变量:

data(mtcars) #load mtcars data
mtcars$carb <- as.integer(mtcars$carb) #set to integer,
                                       #for purposes of illustration

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

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

Error: Problem with `mutate()` input `..1`.
ℹ `..1 = across(c(gear:carb), ~case_when(vs == 1 ~ NA, T ~ .))`.
x must be a logical vector, not a double vector.

如果我在每个变量上单独使用mutate,我会将NA 替换为“carb”的NA_integer_,将NA 替换为“gear”的NA_real_。我不能在这里这样做,因为变量包含不同类型的数据。

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

谢谢!

【问题讨论】:

  • 请提供样本数据,如果可以,请使用dput(.)。请在给定示例输入的情况下包含您的预期输出。
  • 我不确定如何使用 dput,但我添加了一个使用内置 mtcars 数据重现问题的示例——希望没问题。我添加了我的预期输出。谢谢!
  • 如何使用dput:输入dput(x)(或dput(head(x,10)) 或最小但足以满足您的问题需求的内容),复制包含前导structure( 的输出,尾随/最后),以及介于两者之间的所有内容,然后将您的问题粘贴到代码块中。 (实际上非​​常简单。该函数的美妙之处在于它为我们提供了您正在使用的数据的完全明确的视图,而普通的控制台打印输出掩盖了factorDate/POSIXct、list-columns、等等。当数据中有空格时,它也很有帮助。
  • 但是...您对mtcars 的使用同样“简单”、有用,而且通常比向我们提供您的数据更好,只要问题可以充分在样本数据集中建模。谢谢!
  • 非常有帮助,谢谢!

标签: r dplyr typeerror na


【解决方案1】:

另一种选择是使用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 ~ .
  )))

但由于@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

【讨论】:

  • 快捷方式:vs == 1 ~ .[NA] 将始终在 if_elsecase_when 等类敏感函数中提供适当的 NA-type。 (有时我需要使用.[NA][1]。)它只是有点快一点,但我认为代码高尔夫超过了if (is.integer(.))的冗长以及函数堆栈开销.
  • @r2evans。谢谢。这真的很有用,如果不是很棒的话。 (; 实际上我给自己写了一个自定义函数,它使用多个 ifs 来获得正确的类型。:D
  • 前段时间我也开始走这条路,直到我意识到检查每个类(包括inherits(., "POSIXt")inherits(., "Date"))都会增加堆栈和运行时。在意识到至少有 6 种类型的 NA 时,我意识到可能有第 7 种我不知道,因此 .[NA] 实际上是在使用 R 中已经内置的机制来做到这一点直接:`[` 在我遇到的每一堂课中都毫不含糊。所以我现在用它作为未来的证明,以防我错过了什么。从那以后我再也没有回头:-)
  • 在我的一个包中,我什至硬编码了NA_POSIXt_NA_Date_ 的常量。
  • @r2evans 关于“我不认为.[NA] 是正式的东西”:因为在?Extract 中描述了索引中的NAs - “提取时,一个数字,逻辑或字符NA 索引选择一个未知元素,因此逻辑、整数、数字、复数或字符结果的相应元素中返回NA”-我会称之为相当正式。如果我理解正确;) 可以在here 找到类似设置中的另一种“强制方法”。干杯
猜你喜欢
  • 1970-01-01
  • 2021-04-28
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
  • 2020-01-27
  • 2019-01-08
相关资源
最近更新 更多