melt.data.table na.rm 作为 measure.vars 列表的第一个元素
melt.data.table with na.rm for first element of list of measure.vars
我想探索 melt
data.table
的最佳方法 na.rm
仅适用于 measure.vars
.[=38 列表的第一个元素=]
我有一个data.table
如下:
library(data.table)
library(lubridate)
dt.master <- data.table(user = seq(1,5),
visit_id = c(2,4,NA,4,8),
visit_date = c(dmy("10/02/2018"), dmy("11/04/2018"), NA, dmy("02/03/2018"), NA),
offer_id = c(1,3,NA,NA,NA),
offer_date = c(dmy("15/02/2018"), dmy("18/04/2018"), NA, NA, NA))
与dt.master
:
user visit_id visit_date offer_id offer_date
1: 1 2 2018-02-10 1 2018-02-15
2: 2 4 2018-04-11 3 2018-04-18
3: 3 NA <NA> NA <NA>
4: 4 4 2018-03-02 NA <NA>
5: 5 8 <NA> NA <NA>
我想为每个用户获取商业 activity 的 "story"(即:他们的访问量和报价)。
dt.melted <- melt(dt.master,
id.vars = "user",
measure.vars = list(c("visit_id", "offer_id"), c("visit_date", "offer_date")),
variable.name = "level",
value.name = c("level_id", "level_date"))
与dt.melted
:
user level level_id level_date
1: 1 1 2 2018-02-10
2: 2 1 4 2018-04-11
3: 3 1 NA <NA>
4: 4 1 4 2018-03-02
5: 5 1 8 <NA>
6: 1 2 1 2018-02-15
7: 2 2 3 2018-04-18
8: 3 2 NA <NA>
9: 4 2 NA <NA>
10: 5 2 NA <NA>
但是,我不希望 NA
s 出现在 level_id
列中,即:
user level level_id level_date
1: 1 1 2 2018-02-10
2: 2 1 4 2018-04-11
3: 4 1 4 2018-03-02
4: 5 1 8 <NA>
5: 1 2 1 2018-02-15
6: 2 2 3 2018-04-18
遗憾的是,样本的数据质量实在是太差了,所以level_date
并不总是可用的。因此,na.rm = T
无效,因为我会得到:
dt.melted.na <- melt(dt.master,
id.vars = "user",
measure.vars = list(c("visit_id", "offer_id"), c("visit_date", "offer_date")),
variable.name = "level",
value.name = c("level_id", "level_date"),
na.rm = TRUE)
与dt.melted.na
:
user level level_id level_date
1: 1 1 2 2018-02-10
2: 2 1 4 2018-04-11
3: 4 1 4 2018-03-02
4: 1 2 1 2018-02-15
5: 2 2 3 2018-04-18
有没有办法只对 measure.vars
中列表的第一个元素使用 na.rm = TRUE
? 我目前正在探索其他解决方法(例如填充visit_date
and offer_date
with "false" dates when visit_id
and offer_id
are available),但我想知道是否有一个优雅的解决方案。
如果 melt()
的 na.rm
参数采用一个布尔值向量,一个代表 measure.vars
列表中的每个元素,例如
melt(dt.master,
id.vars = "user",
measure.vars = list(c("visit_id", "offer_id"), c("visit_date", "offer_date")),
variable.name = "level",
value.name = c("level_id", "level_date"),
na.rm = c(TRUE, FALSE)) # not possible with data.table v1.11.0
由于此功能尚未实现,另一种方法是 在使用 na.rm = TRUE
将 重塑为长格式后添加缺失的行。 OP 有 ,由于问题大小和内存限制,必须使用 na.rm = TRUE
。
rbind(
dt.melted.na,
dt.master[!is.na(visit_id) & is.na(visit_date), .(user, level = 1L, level_id = visit_id)],
dt.master[!is.na(offer_id) & is.na(offer_date), .(user, level = 2L, level_id = offer_id)],
fill = TRUE
)
user level level_id level_date
1: 1 1 2 2018-02-10
2: 2 1 4 2018-04-11
3: 4 1 4 2018-03-02
4: 1 2 1 2018-02-15
5: 2 2 3 2018-04-18
6: 5 1 8 <NA>
这种方法相当笨拙和冗长,但可能有助于克服内存限制。它本质上是对缺失行的重塑 "by hand"。
还有另一种可能不那么冗长的选择:
incomplete_rows <-
melt(dt.master[!is.na(visit_id) & is.na(visit_date) | !is.na(offer_id) & is.na(offer_date)],
id.vars = "user",
measure.vars = list(c("visit_id", "offer_id"), c("visit_date", "offer_date")),
variable.name = "level",
value.name = c("level_id", "level_date"))[!is.na(level_id)]
rbind(
dt.melted.na,
incomplete_rows
)
这里,所有行都是从 dt.master
中挑选出来的,这些行是部分不完整的,重新整形为长格式,然后过滤。如果这只涉及 dt.master
行的一小部分,这也可能适用于有限的内存。
我想探索 melt
data.table
的最佳方法 na.rm
仅适用于 measure.vars
.[=38 列表的第一个元素=]
我有一个data.table
如下:
library(data.table)
library(lubridate)
dt.master <- data.table(user = seq(1,5),
visit_id = c(2,4,NA,4,8),
visit_date = c(dmy("10/02/2018"), dmy("11/04/2018"), NA, dmy("02/03/2018"), NA),
offer_id = c(1,3,NA,NA,NA),
offer_date = c(dmy("15/02/2018"), dmy("18/04/2018"), NA, NA, NA))
与dt.master
:
user visit_id visit_date offer_id offer_date
1: 1 2 2018-02-10 1 2018-02-15
2: 2 4 2018-04-11 3 2018-04-18
3: 3 NA <NA> NA <NA>
4: 4 4 2018-03-02 NA <NA>
5: 5 8 <NA> NA <NA>
我想为每个用户获取商业 activity 的 "story"(即:他们的访问量和报价)。
dt.melted <- melt(dt.master,
id.vars = "user",
measure.vars = list(c("visit_id", "offer_id"), c("visit_date", "offer_date")),
variable.name = "level",
value.name = c("level_id", "level_date"))
与dt.melted
:
user level level_id level_date
1: 1 1 2 2018-02-10
2: 2 1 4 2018-04-11
3: 3 1 NA <NA>
4: 4 1 4 2018-03-02
5: 5 1 8 <NA>
6: 1 2 1 2018-02-15
7: 2 2 3 2018-04-18
8: 3 2 NA <NA>
9: 4 2 NA <NA>
10: 5 2 NA <NA>
但是,我不希望 NA
s 出现在 level_id
列中,即:
user level level_id level_date
1: 1 1 2 2018-02-10
2: 2 1 4 2018-04-11
3: 4 1 4 2018-03-02
4: 5 1 8 <NA>
5: 1 2 1 2018-02-15
6: 2 2 3 2018-04-18
遗憾的是,样本的数据质量实在是太差了,所以level_date
并不总是可用的。因此,na.rm = T
无效,因为我会得到:
dt.melted.na <- melt(dt.master,
id.vars = "user",
measure.vars = list(c("visit_id", "offer_id"), c("visit_date", "offer_date")),
variable.name = "level",
value.name = c("level_id", "level_date"),
na.rm = TRUE)
与dt.melted.na
:
user level level_id level_date
1: 1 1 2 2018-02-10
2: 2 1 4 2018-04-11
3: 4 1 4 2018-03-02
4: 1 2 1 2018-02-15
5: 2 2 3 2018-04-18
有没有办法只对 measure.vars
中列表的第一个元素使用 na.rm = TRUE
? 我目前正在探索其他解决方法(例如填充visit_date
and offer_date
with "false" dates when visit_id
and offer_id
are available),但我想知道是否有一个优雅的解决方案。
如果 melt()
的 na.rm
参数采用一个布尔值向量,一个代表 measure.vars
列表中的每个元素,例如
melt(dt.master,
id.vars = "user",
measure.vars = list(c("visit_id", "offer_id"), c("visit_date", "offer_date")),
variable.name = "level",
value.name = c("level_id", "level_date"),
na.rm = c(TRUE, FALSE)) # not possible with data.table v1.11.0
由于此功能尚未实现,另一种方法是 在使用 na.rm = TRUE
将 重塑为长格式后添加缺失的行。 OP 有 na.rm = TRUE
。
rbind(
dt.melted.na,
dt.master[!is.na(visit_id) & is.na(visit_date), .(user, level = 1L, level_id = visit_id)],
dt.master[!is.na(offer_id) & is.na(offer_date), .(user, level = 2L, level_id = offer_id)],
fill = TRUE
)
user level level_id level_date 1: 1 1 2 2018-02-10 2: 2 1 4 2018-04-11 3: 4 1 4 2018-03-02 4: 1 2 1 2018-02-15 5: 2 2 3 2018-04-18 6: 5 1 8 <NA>
这种方法相当笨拙和冗长,但可能有助于克服内存限制。它本质上是对缺失行的重塑 "by hand"。
还有另一种可能不那么冗长的选择:
incomplete_rows <-
melt(dt.master[!is.na(visit_id) & is.na(visit_date) | !is.na(offer_id) & is.na(offer_date)],
id.vars = "user",
measure.vars = list(c("visit_id", "offer_id"), c("visit_date", "offer_date")),
variable.name = "level",
value.name = c("level_id", "level_date"))[!is.na(level_id)]
rbind(
dt.melted.na,
incomplete_rows
)
这里,所有行都是从 dt.master
中挑选出来的,这些行是部分不完整的,重新整形为长格式,然后过滤。如果这只涉及 dt.master
行的一小部分,这也可能适用于有限的内存。