同时排序、行过滤器和列-select 与 data.table
Simultaneous order, row-filter and column-select with data.table
我正在尝试在 R 中的一行中执行多个步骤,以 select 来自具有多个条件的 data.table (dt) 的值。
例如:
set.seed(123)
dt <- data.table(id = rep(letters[1:2],2),
time = rnorm(4),
value = rnorm(4)*100)
# id time value
# 1: a -0.56047565 12.92877
# 2: b -0.23017749 171.50650
# 3: a 1.55870831 46.09162
# 4: b 0.07050839 -126.50612
# Now I want to select the last (maximum time) value from id == "a"
# My pseudo data.table code looks like this
dt[order(time) & id == "a" & .N, value]
# [1] 12.92877 46.09162
我不想获取这两个值,而是只想获取最后一个值(具有更高的时间值)。
如果我一步一步地做,它会起作用:
dt <- dt[order(time) & id == "a"]
dt[.N, value]
# [1] 46.09162
奖金:
如何在不复制 data.table 的情况下订购 data.table:即
dt <- dt[order(time)]
没有 <-
。类似于 :=
运算符,例如 dt[, new_val := value*2]
中的运算符,它创建新变量而不复制整个 data.table.
谢谢,任何想法都非常感谢!
第一个问题,试试
dt[id == "a", value[which.max(time)]]
## [1] 46.09162
对于奖励问题,请尝试 setorder
function 它将对您的数据进行适当的排序(您也可以通过在 time
前面添加 -
来按降序排序)
setorder(dt, time)
dt
# id time value
# 1: a -0.56047565 12.92877
# 2: b -0.23017749 171.50650
# 3: b 0.07050839 -126.50612
# 4: a 1.55870831 46.09162
此外,如果您已经按时间对数据进行排序,则可以同时进行 - 按参考排序和 select value
按条件排序 - 在单行中
setorder(dt, time)[id == "a", value[.N]]
我知道这是一个较旧的问题,但我想补充一些内容。有一个类似的问题,我偶然发现了这个问题,虽然 David Arenburg 的回答确实提供了这个问题的解决方案,但我在尝试从过滤和排序的 data.table 中获取 replace/overwrite 值时遇到了麻烦,所以在这里是另一种方法,它还允许您将 <-
调用直接应用于过滤和排序的 data.tabe.
关键是 data.table 让你可以将几个 []
相互连接起来。
示例:
dt[id=="a", ][order(time), ][length(value), "value"] <- 0
这也适用于多个条目,只需提供一个 suitable 向量作为替换值。
但是请注意,列表对象 .N
需要替换为例如列的长度,因为 data.table 在 i
中的这个位置需要一个整数,而你想要在 j
中 select 的列需要被 ""
包裹.
我发现这是更直观的方法,它不仅可以过滤数据 table,还可以操纵其值,而无需担心临时 tables。
我正在尝试在 R 中的一行中执行多个步骤,以 select 来自具有多个条件的 data.table (dt) 的值。
例如:
set.seed(123)
dt <- data.table(id = rep(letters[1:2],2),
time = rnorm(4),
value = rnorm(4)*100)
# id time value
# 1: a -0.56047565 12.92877
# 2: b -0.23017749 171.50650
# 3: a 1.55870831 46.09162
# 4: b 0.07050839 -126.50612
# Now I want to select the last (maximum time) value from id == "a"
# My pseudo data.table code looks like this
dt[order(time) & id == "a" & .N, value]
# [1] 12.92877 46.09162
我不想获取这两个值,而是只想获取最后一个值(具有更高的时间值)。
如果我一步一步地做,它会起作用:
dt <- dt[order(time) & id == "a"]
dt[.N, value]
# [1] 46.09162
奖金:
如何在不复制 data.table 的情况下订购 data.table:即
dt <- dt[order(time)]
没有 <-
。类似于 :=
运算符,例如 dt[, new_val := value*2]
中的运算符,它创建新变量而不复制整个 data.table.
谢谢,任何想法都非常感谢!
第一个问题,试试
dt[id == "a", value[which.max(time)]]
## [1] 46.09162
对于奖励问题,请尝试 setorder
function 它将对您的数据进行适当的排序(您也可以通过在 time
前面添加 -
来按降序排序)
setorder(dt, time)
dt
# id time value
# 1: a -0.56047565 12.92877
# 2: b -0.23017749 171.50650
# 3: b 0.07050839 -126.50612
# 4: a 1.55870831 46.09162
此外,如果您已经按时间对数据进行排序,则可以同时进行 - 按参考排序和 select value
按条件排序 - 在单行中
setorder(dt, time)[id == "a", value[.N]]
我知道这是一个较旧的问题,但我想补充一些内容。有一个类似的问题,我偶然发现了这个问题,虽然 David Arenburg 的回答确实提供了这个问题的解决方案,但我在尝试从过滤和排序的 data.table 中获取 replace/overwrite 值时遇到了麻烦,所以在这里是另一种方法,它还允许您将 <-
调用直接应用于过滤和排序的 data.tabe.
关键是 data.table 让你可以将几个 []
相互连接起来。
示例:
dt[id=="a", ][order(time), ][length(value), "value"] <- 0
这也适用于多个条目,只需提供一个 suitable 向量作为替换值。
但是请注意,列表对象 .N
需要替换为例如列的长度,因为 data.table 在 i
中的这个位置需要一个整数,而你想要在 j
中 select 的列需要被 ""
包裹.
我发现这是更直观的方法,它不仅可以过滤数据 table,还可以操纵其值,而无需担心临时 tables。