如何根据R中的条件创建新变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何根据R中的条件创建新变量相关的知识,希望对你有一定的参考价值。

我正在尝试根据某些条件创建一个新变量。

我的数据看起来像

a   b
1   NA
2   3
3   3
NA  2
NA  NA

我想要的是变量c这样的

  • a不是NA时,bNAc = a
  • aNA时,b不是NAc = b
  • aNA时,bNAc = NA
  • a不是NA时,b不是NA,而a == bc = a
  • a不是NA时,b不是NA,而a != bc = "multiple_values"

我怎样才能做到这一点?

似乎ifelse()不能做我想要的。

答案

除了一个条件,即'a','b'中的非NA元素,并且它们彼此不相等,所有其他条件都满足coalesce。所以,我们可以通过应用case_when做一个coalesce来根据最后一个条件和所有其他条件生成“multiple_values”

library(dplyr)
df1 %>%
     mutate(c = case_when(!is.na(a) & !is.na(b) & a != b ~ "multiple_values", 
               TRUE ~ as.character(coalesce(a, b))))
#   a  b               c
#1  1 NA               1
#2  2  3 multiple_values
#3  3  3               3
#4 NA  2               2
#5 NA NA            <NA>

data

df1 <- structure(list(a = c(1L, 2L, 3L, NA, NA), b = c(NA, 3L, 3L, 2L, 
 NA)), class = "data.frame", row.names = c(NA, -5L))
另一答案

在基地R你可以使用within

dat <- within(dat, {
  c <- NA
  c[!is.na(a) & is.na(b)] <- a[!is.na(a) & is.na(b)]
  c[is.na(a) & !is.na(b)] <- b[is.na(a) & !is.na(b)]
  # # c[is.na(a) & is.na(b)] <- NA  # redundant
  c[!is.na(a) & !is.na(b) & a == b] <- a[!is.na(a) & !is.na(b) & a == b]
  c[!is.na(a) & !is.na(b) & a != b] <- "multiple_values"
})

dat
#    a  b               c
# 1  1 NA               1
# 2  2  3 multiple_values
# 3  3  3               3
# 4 NA  2               2
# 5 NA NA            <NA>

数据:dat <- data.frame(a=c(1:3, NA, NA), b=c(NA, 3, 3, 2, NA))

另一答案

ifelse可以做你想要的,但只是会有很多嵌套语句

df$c <- with(df, ifelse(!is.na(a) & is.na(b), a, 
           ifelse(is.na(a) & !is.na(b), b, 
              ifelse(is.na(a) & is.na(b), NA, 
                ifelse(!is.na(a) & !is.na(b) & a == b, a, "multiple_values")))))


df
#   a  b               c
#1  1 NA               1
#2  2  3 multiple_values
#3  3  3               3
#4 NA  2               2
#5 NA NA            <NA>
另一答案

这是另一个基本R答案,它使用mapply循环遍历值对,这是一个简单的函数,它将它们组合并删除NAs,并使用switch来决定结果。

df1$c <-
 mapply(function(x, y) {
                 z <- c(x, y)
                 z <- unique(z[!is.na(z)])
                 switch(length(z) + 1L, NA, z, "many")
        }, df1$a, df1$b)

返回

df1
   a  b    c
1  1 NA    1
2  2  3 many
3  3  3    3
4 NA  2    2
5 NA NA <NA>
另一答案

使用data.table,您可以:

df1 <- structure(list(a = c(1L, 2L, 3L, NA, NA), b = c(NA, 3L, 3L, 2L, 
                                                       NA)), class = "data.frame", row.names = c(NA, -5L))
library(data.table)
df1 <- as.data.table(df1)
df1[, c:="NONE"]
df1[!is.na(a) & is.na(b), c:=a] 
df1[is.na(a) & !is.na(b), c:=b] 
df1[is.na(a) & is.na(b),  c:=NA] 
df1[!is.na(a) & !is.na(b) & a==b,  c:=a] 
df1[!is.na(a) & !is.na(b) & a!=b,  c:="multiple values"] 

以上是关于如何根据R中的条件创建新变量的主要内容,如果未能解决你的问题,请参考以下文章

R If then do - 如何根据条件创建变量

根据 R 中的条件包含满足条件创建一个新列

如何根据一个数据帧中的列值和R中另一个数据帧的列标题名称有条件地创建新列

我可以根据 r 中的其他两个条件创建一个变量的多个类别吗? [复制]

根据 R 列中的部分匹配创建新变量

如何根据其他变量和时间间隔创建新变量(在 R 中)