使用data.table同时进行顺序,行过滤和列选择

Dav*_*vid 4 r data.table

我试图在R中的一行中执行多个步骤,以从具有多个条件的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  
Run Code Online (Sandbox Code Playgroud)

而不是获取我想要的两个值只有最后一个值(具有更高的时间值).

如果我一步一步地做到这一点:

dt <- dt[order(time) & id == "a"]
dt[.N, value]
# [1] 46.09162
Run Code Online (Sandbox Code Playgroud)

奖金:

如何在不复制data.table的情况下订购data.table:ie

dt <- dt[order(time)]
Run Code Online (Sandbox Code Playgroud)

没有<-.类似于-operator,:=例如在dt[, new_val := value*2]其中创建新变量而不复制整个data.table.

谢谢,非常感谢任何想法!

Dav*_*urg 7

对于你的第一个问题,试试吧

dt[id == "a", value[which.max(time)]]
## [1] 46.09162
Run Code Online (Sandbox Code Playgroud)

对于奖金问题,请尝试使用setorder功能,这将(通过增加你也可以订购降序排列到位命令你的数据-在前面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
Run Code Online (Sandbox Code Playgroud)

此外,如果您已按时间订购数据,则可以同时执行 - 按引用顺序并按value条件选择 - 单行

setorder(dt, time)[id == "a", value[.N]]
Run Code Online (Sandbox Code Playgroud)


N. *_*aks 5

我知道这是一个较旧的问题,但我想补充一些内容。有一个类似的问题,我偶然发现了这个问题,尽管 David Arenburg 的回答确实为这个确切的问题提供了解决方案,但我在尝试替换/覆盖过滤和排序的 data.table 中的值时遇到了问题,所以这里是另一种方法它还允许您将<-调用直接应用于过滤和排序的 data.tabe。

关键是 data.table 可以让你将几个[]彼此连接起来。

例子:

dt[id=="a", ][order(time), ][length(value), "value"] <- 0
Run Code Online (Sandbox Code Playgroud)

这也适用于多个条目,只需提供一个合适的向量作为替换值。

但是请注意,.Nwhich 是列表对象需要替换为例如列的长度,因为 data.table 需要在此位置的整数,i并且您要选择的列j需要由 包装""

我发现这是一种更直观的方式,它不仅可以让您过滤数据表,还可以操作其值而无需担心临时表。