Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/82.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R lapply在未按预期工作的行中查找最大值_R_Data.table_Lapply - Fatal编程技术网

R lapply在未按预期工作的行中查找最大值

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

我正在尝试使用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
  }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中添加更多过滤。你知道有什么办法可以让它发挥作用吗?