用条件NA定义函数

时间:2018-03-28 14:10:32

标签: r function dataframe each

我有以下数据框

date1         date2           Date3        n_var
2017-02-01    2019-02-04      2018-04-01   2
2016-02-01    NA              2017-01-02   3
2017-02-01    2019-02-04      2020-04-01   7
2016-02-01    2019-02-04      2020-04-01   7

我想要这个

date1         date2           Date3        price 
2017-02-01    2019-02-04      2018-04-01   2
2016-02-01    NA              2017-01-02   3
2017-02-01    2019-02-04      2020-04-01   NA
2016-02-01    2019-02-04      2020-04-01   NA

规则:

date3< date1我们在列n_var中输入na date2是na和date2< date3 - >我们把na放在n_var栏中 否则我们想要n_var

的每一行的值

这是我的代码:

f_NA <- function(nvar)
    for(i in 1:nrow(df)) {
        df$nvar[i,] <- ifelse((date3<date1), NA,
                                 ifelse(((!is.na(date2)) & date3>date2), NA,df$nvar[i,]))
                          }         

但它确实走了?

5 个答案:

答案 0 :(得分:2)

一种方式:

library(data.table)
setDT(DF)

f = function(DF, nvar) DF[!(date2 >= Date3 & Date3 >= date1), (nvar) := NA][]

f(DF, "n_var")

它的作用类似于DF[filter, edit columns]。您不需要单独处理date2为NA的案例,因为无论如何都会在过滤期间跳过这些案例。

请注意,此函数会修改输入表,而不是仅返回包含列编辑的新表。

数据

DF = structure(list(date1 = structure(c(17198, 16832, 17198, 16832
), class = "Date"), date2 = structure(c(17931, NA, 17931, 17931
), class = "Date"), Date3 = structure(c(17622, 17168, 18353, 
18353), class = "Date"), n_var = c(2L, 3L, 7L, 7L)), .Names = c("date1", 
"date2", "Date3", "n_var"), row.names = c(NA, -4L), class = "data.frame")

答案 1 :(得分:1)

这是尝试它的一种方法。 ifelse构造本应该起作用,但不确定那里发生了什么。

date1 <- c("2017-02-01", "2016-02-01", "2017-02-01", "2016-02-01")       
date2 <- c("2019-02-04", NA, "2019-02-04", "2019-02-04")    
date3 <- c("2018-04-01", "2017-01-02", "2020-04-01", "2020-04-01")
n_var <- c(2,3,7,7)

df <- cbind.data.frame(date1,date2, date3, n_var)
df$date1 <- as.Date(df$date1, format = "%Y-%m-%d")
df$date2 <- as.Date(df$date2, format = "%Y-%m-%d")
df$date3 <- as.Date(df$date3, format = "%Y-%m-%d")

idx1 <- df$date3<df$date1
idx2 <- !is.na(df$date2) & df$date2<df$date3

df$n_var[c(idx1 | idx2)] <- NA

希望这有帮助。

答案 2 :(得分:1)

尝试

f_NA <- function(nvar){
  condition1 <- which(df$date3 < df$date1)
  condition2 <- intersect(which(!is.na(df$date2)), which(df$date2 < df$date3))
  cc <- union(condition1, condition2)
  df$nvar[cc] <- NA
  return(df)
}

答案 3 :(得分:0)

ifelse适用于向量,因此您不需要使用[i,]索引或循环。相反,直接使用: (这段代码对我有用,感谢Drj建立数据)

date1 <- c("2017-02-01", "2016-02-01", "2017-02-01", "2016-02-01")       
date2 <- c("2019-02-04", NA, "2019-02-04", "2019-02-04")    
date3 <- c("2018-04-01", "2017-01-02", "2020-04-01", "2020-04-01")
n_var <- c(2,3,7,7)
df <- cbind.data.frame(date1,date2, date3, n_var)
df$date1 <- as.Date(df$date1, format = "%Y-%m-%d")
df$date2 <- as.Date(df$date2, format = "%Y-%m-%d")
df$date3 <- as.Date(df$date3, format = "%Y-%m-%d")
f_NA <- ifelse(df$date3<df$date1, NA,
               ifelse(((!is.na(df$date2)) & df$date3>df$date2), NA,df$n_var))

答案 4 :(得分:-2)

您是否尝试在功能中使用NA_character_代替NA