R lapply在未按预期工作的行中查找最大值
我正在尝试使用Lappy在data.table的行中查找最大日期。我有一些行,行中的所有值都是NA,在本例中,我想返回一个特定的日期。我写了一个函数来实现这一点,但是我没有得到我期望的结果R lapply在未按预期工作的行中查找最大值,r,data.table,lapply,R,Data.table,Lapply,我正在尝试使用Lappy在data.table的行中查找最大日期。我有一些行,行中的所有值都是NA,在本例中,我想返回一个特定的日期。我写了一个函数来实现这一点,但是我没有得到我期望的结果 library(data.table) my.max = function(x){ if(all(is.na(x))){ return(as.Date("9999-12-01")) #we can use this to identify which BPIDs have no end date
library(data.table)
my.max = function(x){
if(all(is.na(x))){
return(as.Date("9999-12-01")) #we can use this to identify which BPIDs have no end date
}else{
return(max(x, na.rm = T))
}
}
DT = data.table("Date1" = c(as.Date("2015-12-30"),NA, NA), "Date2" = c(as.Date("2013-02-04"), as.Date("2014-01-01"), NA))
DT[ , "Row" := 1:.N]
DT[ , "Max_Date" := lapply(.SD, my.max), by = .(Row), .SDcols = c("Date1", "Date2")]
这是回报
> DT
Date1 Date2 Row Max_Date
1: 2015-12-30 2013-02-04 1 2015-12-30
2: <NA> 2014-01-01 2 9999-12-01
3: <NA> <NA> 3 9999-12-01
>DT
日期1日期2行最大日期
1: 2015-12-30 2013-02-04 1 2015-12-30
2: 2014-01-01 2 9999-12-01
3: 3 9999-12-01
因此,如果所有值都是NA,则它确实有效,但如果其中一个值是NA,则它也会返回9999-12-01。我将打印函数放入my.max以了解发生了什么,它看起来一次只传入一个x值。这就解释了为什么all(is.na(x))
是真的,但我希望它在行中传递两个日期的向量。否则,它如何知道取最大值
如何更改函数,使其仅在其他两个日期均为NA时返回9999-12-01?请尝试以下方法:
library(data.table)
my.max <- function(x){
if(all(is.na(x))){
return("9999-12-01")
}else{
return(max(x, na.rm = T))
}
}
DT <- data.table("Date1" = c(as.Date("2015-12-30"),NA, NA), "Date2" = c(as.Date("2013-02-04"), as.Date("2014-01-01"), NA))
print(DT)
DT[ , "Max_Date" ] <- apply(DT, 1, my.max)
print(DT)
> DT <- data.table("Date1" = c(as.Date("2015-12-30"),NA, NA), "Date2" = c(as.Date("2013-02-04"), as.Date("2014-01-01"), NA))
> print(DT)
Date1 Date2
1: 2015-12-30 2013-02-04
2: <NA> 2014-01-01
3: <NA> <NA>
> DT[ , "Max_Date" ] <- apply(DT, 1, my.max)
> print(DT)
Date1 Date2 Max_Date
1: 2015-12-30 2013-02-04 2015-12-30
2: <NA> 2014-01-01 2014-01-01
3: <NA> <NA> 9999-12-01
库(data.table)
my.max试试这个:
library(data.table)
my.max <- function(x){
if(all(is.na(x))){
return("9999-12-01")
}else{
return(max(x, na.rm = T))
}
}
DT <- data.table("Date1" = c(as.Date("2015-12-30"),NA, NA), "Date2" = c(as.Date("2013-02-04"), as.Date("2014-01-01"), NA))
print(DT)
DT[ , "Max_Date" ] <- apply(DT, 1, my.max)
print(DT)
> DT <- data.table("Date1" = c(as.Date("2015-12-30"),NA, NA), "Date2" = c(as.Date("2013-02-04"), as.Date("2014-01-01"), NA))
> print(DT)
Date1 Date2
1: 2015-12-30 2013-02-04
2: <NA> 2014-01-01
3: <NA> <NA>
> DT[ , "Max_Date" ] <- apply(DT, 1, my.max)
> print(DT)
Date1 Date2 Max_Date
1: 2015-12-30 2013-02-04 2015-12-30
2: <NA> 2014-01-01 2014-01-01
3: <NA> <NA> 9999-12-01
库(data.table)
my.max这里有一种方法可以奏效。它将多个语句封装在{}
中以形成一个代码块:
DT[, "this" := {temp=pmax(Date1, Date2, na.rm=TRUE);
temp[is.na(temp)] = as.Date("9999-12-01"); temp}]
返回
DT
Date1 Date2 this
1: 2015-12-30 2013-02-04 2015-12-30
2: <NA> 2014-01-01 2014-01-01
3: <NA> <NA> 9999-12-01
这样,您就不必在每一行中循环,因为每一行可能会非常慢
虽然我不建议按行处理
DT[ , "Row" := 1:.N]
DT[ , "Max_Date" := my.max(unlist(.SD)), by = .(Row), .SDcols = c("Date1", "Date2")]
将为本例生成相同的输出。这里有一种方法可以工作。它将多个语句封装在{}
中以形成一个代码块:
DT[, "this" := {temp=pmax(Date1, Date2, na.rm=TRUE);
temp[is.na(temp)] = as.Date("9999-12-01"); temp}]
返回
DT
Date1 Date2 this
1: 2015-12-30 2013-02-04 2015-12-30
2: <NA> 2014-01-01 2014-01-01
3: <NA> <NA> 9999-12-01
这样,您就不必在每一行中循环,因为每一行可能会非常慢
虽然我不建议按行处理
DT[ , "Row" := 1:.N]
DT[ , "Max_Date" := my.max(unlist(.SD)), by = .(Row), .SDcols = c("Date1", "Date2")]
将为该示例生成相同的输出。顺便说一句,我忘了包含DT[,“Row”:=1:.N],但您可以将其添加回原始帖子中的相同位置,您将得到想要的信息。谢谢您的回复。不过我不想使用apply,因为它首先将其转换为矩阵,所以速度相当慢。顺便说一句,我忘了包括DT[,“Row”:=1:.N],但您可以将其添加回原始帖子中的相同位置,您将得到想要的信息。谢谢您的回复。不过我不想使用apply,因为它首先将其转换为矩阵,所以速度相当慢。感谢您的回复。如果可能的话,我想我更愿意使用Lappy,因为我以后可能需要在max date中添加更多过滤。你知道有什么方法可以让它发挥作用吗?谢谢你的回复。如果可能的话,我想我更愿意使用Lappy,因为我以后可能需要在max date中添加更多过滤。你知道有什么办法可以让它发挥作用吗?