2017-07-03 167 views
10

我想使用dplyr::case_whendplyr::mutate创建一个新的变量,我设置一些值丢失,同时重新编码其它值。与dplyr避免类型冲突:: case_when

但是,如果我尝试值设置为NA,我得到一个错误,说我们不能创建变量new因为NA s为逻辑:

Error in mutate_impl(.data, dots) :
Evaluation error: must be type double, not logical.

有没有一种办法值设置为NA数据帧中使用此非逻辑向量?

library(dplyr)  

# Create data 
df <- data.frame(old = 1:3) 

# Create new variable 
df <- df %>% dplyr::mutate(new = dplyr::case_when(old == 1 ~ 5, 
                old == 2 ~ NA, 
                TRUE ~ old)) 

# Desired output 
c(5, NA, 3) 

回答

10

正如?case_when说:

All RHSs must evaluate to the same type of vector.

你实际上有两种可能性:

1)创建new作为数字矢量

df <- df %>% mutate(new = case_when(old == 1 ~ 5, 
            old == 2 ~ NA_real_, 
            TRUE ~ as.numeric(old))) 

注意NA_real_是该数字版本的NA,而且你必须转换到old数字,因为你创造了它在你的原始数据帧的整数。

你得到:

str(df) 
# 'data.frame': 3 obs. of 2 variables: 
# $ old: int 1 2 3 
# $ new: num 5 NA 3 

2)作为一个整数向量

df <- df %>% mutate(new = case_when(old == 1 ~ 5L, 
            old == 2 ~ NA_integer_, 
            TRUE ~ old)) 

这里,5L部队5到整数类型创建new,并NA_integerNA整数版本。

所以这次new是整数

str(df) 
# 'data.frame': 3 obs. of 2 variables: 
# $ old: int 1 2 3 
# $ new: int 5 NA 3 
+2

你也可以做'as.numeric(NA)'或'as.integer(NA)'的'NA'情况下,如'NA_real_'和'NA_integer_'有点令人讨厌,并且很少在这样的事情之外使用。 – Marius

+0

不错。此外,要显示:相同(NA_real_,as.numeric(NA))会生成TRUE。 – user3614648

+0

@hadley这个答案现在已经很清楚,我,但我花了一段时间才搞清楚。在tidyverse'case_when'文档中有一个这样的例子会很有帮助。在我的情况丢失了所有值分组的数据时,平均(X [1:2],na.rm = T)中产生的NaN结果。将这些情况重新编码为NA_real_,以修正它。 –

2

试试这个吗?

df %>% dplyr::mutate(new = dplyr::case_when(.$old == 1 ~ 5, 
                .$old == 2 ~ NA_real_, 
                TRUE~.$old)) 

> df 
    old new 
1 1 5 
2 2 NA 
3 3 3