如何基于R中的条件创建新变量

时间:2019-04-14 06:40:26

标签: r variables

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

我的数据看起来像

#if necessary
#df['date'] = pd.to_datetime(df['date'])

df = df.groupby(pd.Grouper(freq='m',key='date'))['totalShrs'].last().ffill().reset_index()
#alternative
#df = df.resample('m',on='date')['totalShrs'].last().ffill().reset_index()
print (df)
        date  totalShrs
0 2009-04-30    40000.0
1 2009-05-31    80000.0
2 2009-06-30   110000.0
3 2009-07-31   110000.0
4 2009-08-31   120000.0

我想要的是一个变量a b 1 NA 2 3 3 3 NA 2 NA NA

  • c不是aNAbNA

  • c = aa时,NA不是bNA

  • c = baNAbNA

  • c = NA不是aNA不是bNAa == b

    < / li>
  • c = a不是aNA不是bNAa != b

    < / li>

我该怎么做?

似乎c = "multiple_values"不能满足我的要求。

5 个答案:

答案 0 :(得分:5)

除了其中一个条件(即'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>

数据

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))

答案 1 :(得分:4)

在基数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))

答案 2 :(得分:2)

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>

答案 3 :(得分:2)

这是另一个基本的R答案,它使用mapply遍历值对,这是一个简单的函数,将它们组合并丢弃NA,并使用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>

答案 4 :(得分:1)

使用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"]