为什么我的条件ifelse recode不返回期望值?

eulz3vhy  于 11个月前  发布在  其他
关注(0)|答案(2)|浏览(99)

我正在创建一个新变量,它使用基于几个源变量值的条件“ifelse”语句。
源变量是一个调查问题,在连续的年度调查中更改了名称。因此,当其中一个变量有值时,其他变量(对应于调查的其他年份)就有缺失(“NA”)值。
数据如下:

A  B
[1,]  1 NA
[2,]  2 NA
[3,] NA NA
[4,] NA  1
[5,] NA  2

字符串
我想做的是根据这些规则创建“C”:

If A = 1 or B = 1, C = 1
 If A = 2 or B = 2, C = 2
 If A and B equal something other than 1 or 2, C = NA


这就是我得到的:

A  B  C
1:  1 NA  1
2:  2 NA NA
3: NA NA NA
4: NA  1  1
5: NA  2 NA


因此,在第2行和第5行中,C应该是“2”,而不是“NA”。
这里有一个可重复的例子:

require(tidyverse)
require(dplyr)
require(data.table)

#Create Data
A <- as.numeric(c(1,2,NA,NA,NA))
B <- as.numeric(c(NA,NA,NA,1,2))
df_ <- cbind(A,B)

#Conditional Recode with dplyr
df2 <- df_ %>% data.frame() %>%
  mutate(C = ifelse(A == 1 | B == 1, 1, 
              ifelse(A == 2 | B == 2, 2, NA)))

#Conditional Recode with data.table()
df2 <- df_ %>% data.table() %>% 
  .[ , C := ifelse(A == 1 | B == 1, 1, 
            ifelse(A == 2 | B == 2, 2, NA))]


我怀疑这与R处理NA的方式有关。
有没有人能扔给我一根骨头,在这里?谢谢!:)

q5lcpyga

q5lcpyga1#

使用%in%,而不是==,当NA的混合:

df_ %>% data.frame() %>%
  mutate(C = ifelse(A %in% 1 | B %in% 1, 1, 
                    ifelse(A %in% 2 | B %in% 2, 2, NA)))

#    A  B  C
# 1  1 NA  1
# 2  2 NA  2
# 3 NA NA NA
# 4 NA  1  1
# 5 NA  2  2

字符串
原因是,只要元素是NA==就会返回NA,因为等式比较是未定义的,所以返回NA-而%in%正在测试集合中的每个元素(尽管这里的“集合”只有一个值)。由于没有直接匹配,它返回FALSE。你可以在这里看到一个简单的例子:

x <- c("A", "B", NA, "D")

x == "A"
# [1]  TRUE FALSE NA FALSE

x %in% "A"
# [1]  TRUE FALSE FALSE FALSE


此外,您可能希望使用dplyr::case_when而不是嵌套的ifelse

df_ %>% data.frame() %>%
  mutate(C = case_when(
    A %in% 1 | B %in% 1 ~ 1,
    A %in% 2 | B %in% 2 ~ 2
  ))

#    A  B  C
# 1  1 NA  1
# 2  2 NA  2
# 3 NA NA NA
# 4 NA  1  1
# 5 NA  2  2

2izufjch

2izufjch2#

另一种方法是使用is.na()

library(dplyr)

df1 <- df %>%
  as.data.frame() %>% 
  mutate(C = ifelse(!is.na(A) & A == 1 | !is.na(B) & B == 1, 1,
                    ifelse(!is.na(A) & A == 2 | !is.na(B) & B == 2, 2, NA)))

df1

library(data.table)
df2 <- data.table(df1)
df2[, C := ifelse(!is.na(A) & A == 1 | !is.na(B) & B == 1, 1,
                  ifelse(!is.na(A) & A == 2 | !is.na(B) & B == 2, 2, NA))]
df2

个字符

相关问题