NA 到 data.table 的日期
NA to dates with data.table
我有一个data.table
require(data.table)
require(lubridate)
testDT <- data.table(dateA = c(NA,NA), dateB = c(ymd("20110101"),ymd("20100101")))
testDT
# dateA dateB
# 1: NA 2011-01-01
# 2: NA 2010-01-01
我想做以下操作:如果 dateA 为 NA,则使用与 dateB 中相同的值。我尝试了以下命令:
> testDT[is.na(dateA), dateA := dateB]
Warning message:
In `[.data.table`(testDT, is.na(dateA), `:=`(dateA, dateB)) :
Coerced 'double' RHS to 'logical' to match the column's type; may have truncated precision. Either change the target column ['dateA'] to 'double' first (by creating a new 'double' vector length 2 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'logical' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please.
如您所见,出现了警告,结果很奇怪:
> testDT
dateA dateB
1: TRUE 2011-01-01
2: TRUE 2010-01-01
为什么不起作用?
P.S。我知道我们可以使用:
> testDT[,dateA := ifelse(is.na(dateA), dateB, dateA)]
> testDT
dateA dateB
1: 14975 2011-01-01
2: 14610 2010-01-01
> testDT[,dateA := as.Date(dateA, origin = "1970-01-01")]
> testDT
dateA dateB
1: 2011-01-01 2011-01-01
2: 2010-01-01 2010-01-01
因为第一列只有 NA,所以它猜测它是合乎逻辑的。
如果你添加一个不是 NA 的元素,它会完美地工作:
你的例子多了一个元素
require(data.table)
require(lubridate)
testDT <- data.table(dateA = c(NA,NA, ymd("20110101")), dateB = c(ymd("20110101"),ymd("20100101"), ymd("20100101")))
testDT[is.na(dateA), dateA := dateB]
结果:
> testDT
dateA dateB
1: 14975 2011-01-01
2: 14610 2010-01-01
3: 14975 2010-01-01
那你为什么只有 NA?
您收到该警告消息是因为 dateA
-列没有正确的 class(正如@Emmanuel-Lin 已经提到的那样):
> str(testDT)
Classes ‘data.table’ and 'data.frame': 2 obs. of 2 variables:
$ dateA: logi NA NA
$ dateB: Date, format: "2011-01-01" "2010-01-01"
- attr(*, ".internal.selfref")=<externalptr>
一个可能的解决方案是首先使用 as.Date
或 data.table 的内置日期函数将 dateA
列转换为日期 class:
# convert 'dateA'-column to 'Date'- class first
testDT[, dateA := as.Date(dateA)] # alternatively: as.IDate(dateA)
# fill the 'NA' values in the 'dateA'-column
testDT[is.na(dateA), dateA := dateB][]
给出:
> testDT
dateA dateB
1: 2011-01-01 2011-01-01
2: 2010-01-01 2010-01-01
我有一个data.table
require(data.table)
require(lubridate)
testDT <- data.table(dateA = c(NA,NA), dateB = c(ymd("20110101"),ymd("20100101")))
testDT
# dateA dateB
# 1: NA 2011-01-01
# 2: NA 2010-01-01
我想做以下操作:如果 dateA 为 NA,则使用与 dateB 中相同的值。我尝试了以下命令:
> testDT[is.na(dateA), dateA := dateB]
Warning message:
In `[.data.table`(testDT, is.na(dateA), `:=`(dateA, dateB)) :
Coerced 'double' RHS to 'logical' to match the column's type; may have truncated precision. Either change the target column ['dateA'] to 'double' first (by creating a new 'double' vector length 2 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'logical' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please.
如您所见,出现了警告,结果很奇怪:
> testDT
dateA dateB
1: TRUE 2011-01-01
2: TRUE 2010-01-01
为什么不起作用?
P.S。我知道我们可以使用:
> testDT[,dateA := ifelse(is.na(dateA), dateB, dateA)]
> testDT
dateA dateB
1: 14975 2011-01-01
2: 14610 2010-01-01
> testDT[,dateA := as.Date(dateA, origin = "1970-01-01")]
> testDT
dateA dateB
1: 2011-01-01 2011-01-01
2: 2010-01-01 2010-01-01
因为第一列只有 NA,所以它猜测它是合乎逻辑的。
如果你添加一个不是 NA 的元素,它会完美地工作:
你的例子多了一个元素
require(data.table)
require(lubridate)
testDT <- data.table(dateA = c(NA,NA, ymd("20110101")), dateB = c(ymd("20110101"),ymd("20100101"), ymd("20100101")))
testDT[is.na(dateA), dateA := dateB]
结果:
> testDT
dateA dateB
1: 14975 2011-01-01
2: 14610 2010-01-01
3: 14975 2010-01-01
那你为什么只有 NA?
您收到该警告消息是因为 dateA
-列没有正确的 class(正如@Emmanuel-Lin 已经提到的那样):
> str(testDT) Classes ‘data.table’ and 'data.frame': 2 obs. of 2 variables: $ dateA: logi NA NA $ dateB: Date, format: "2011-01-01" "2010-01-01" - attr(*, ".internal.selfref")=<externalptr>
一个可能的解决方案是首先使用 as.Date
或 data.table 的内置日期函数将 dateA
列转换为日期 class:
# convert 'dateA'-column to 'Date'- class first
testDT[, dateA := as.Date(dateA)] # alternatively: as.IDate(dateA)
# fill the 'NA' values in the 'dateA'-column
testDT[is.na(dateA), dateA := dateB][]
给出:
> testDT dateA dateB 1: 2011-01-01 2011-01-01 2: 2010-01-01 2010-01-01