![](/img/trans.png)
[英]How much RAM (memory) do I save by using an array in R (instead of list, data.frame, data.table)?
[英]Filtering of an array in a list type data.table column
我正在尝试解决一个问题,即我刚刚找到的新路线(卡车),我检查该路线是否已经是我之前路线的一部分。 例如,假设我存储的路由在数据表routelist
, node_list
指的是存储的路由。 我想检查路由(5,6,7,8)所属的行。
library(data.table)
routelist=data.table(id=c(1:3),node_list=list(c(1:6),c(4:7),c(1:10)))
item<-c(5:8)
routelist[sum(item%in%unlist(packlist$node_list))==length(item)]
对于上面的检查,返回所有三行,但是只返回第三行。 我可以通过以下for循环来做到这一点,但它并不快,并没有考虑到顺序(并且应该有一种方法以更好的方式做到这一点)。 item
中节点的顺序很重要,列表不需要是连续的,即项目可以是c(5,7,8)
,应该在第3行返回,而c(5,8,7)
不应该返回。
for(i in 1:3)
{
if(sum(item%in%unlist(packlist[i]$node_list))==length(item))
print(routelist[i])
}
OP的data.table
方法存在两个问题。
by
条款 routelist = data.table(id = 1:3, node_list = list(1:6, 4:7, 1:10))
item <- 5:8
routelist[, sum(item %in% unlist(node_list)) == length(item)]
返回单个TRUE
值,因为
routelist[, unlist(node_list)]
返回一个向量
[1] 1 2 3 4 5 6 4 5 6 7 1 2 3 4 5 6 7 8 9 10
如果按id
分组,我们会得到所需的结果:
routelist[, sum(item %in% unlist(node_list)) == length(item), by = id]
id V1 1: 1 FALSE 2: 2 FALSE 3: 3 TRUE
要么
routelist[routelist[, sum(item %in% unlist(node_list)) == length(item), by = id]$V1]
id node_list 1: 3 1,2,3,4,5,6,
%in%
仅检查外观但不检查订单 表达式sum(item %in% unlist(node_list)) == length(item)
不处理item
中元素的顺序。
由于元素的顺序很重要,因此表达式
isTRUE(all(diff(match(item, unlist(node_list))) > 0))
说明了订单。 match()
返回node_list
中item
元素的位置(如果未找到,则返回NA
)。 如果item
的订单与node_list
的订单相同,则所有位置差异必须为正。 isTRUE()
来覆盖NA
情况。
从而,
item <- c(5, 7, 8)
routelist[routelist[, isTRUE(all(diff(match(item, unlist(node_list))) > 0)), by = id]$V1]
回报
id node_list 1: 3 1,2,3,4,5,6,
尽管存在差距
item <- c(5, 8, 7)
routelist[routelist[, isTRUE(all(diff(match(item, unlist(node_list))) > 0)), by = id]$V1]
回报
Empty data.table (0 rows) of 2 cols: id,node_list
由于错误的订单请求。
来自dplyr
和tidyr
解决方案。
如果订单不重要,可以使用以下方法。 通过检查routelist2
的id
列,很明显id 3是具有正确条件的id。
# Create example dataset
library(data.table)
routelist=data.table(id=c(1:3),node_list=list(c(1:6),c(4:7),c(1:10)))
item<-c(5:8)
# Solution 1
library(dplyr)
library(tidyr)
routelist2 <- routelist %>%
unnest() %>%
group_by(id) %>%
filter(all(item %in% node_list)) %>%
nest()
routelist2
# A tibble: 1 x 2
id data
<int> <list>
1 3 <tibble [10 x 1]>
如果订单很重要,我们可能必须将路径编号转换为字符串,而不是找到正确的字符串模式。 以下方法应该有效。
# Solution 2
item_str <- toString(item)
routelist3 <- routelist %>%
rowwise() %>%
mutate(node_list = toString(node_list)) %>%
filter(grepl(item_str, node_list)) %>%
ungroup()
routelist3
# A tibble: 1 x 2
id node_list
<int> <chr>
1 3 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
以下考虑的情况时,在节点item2
是不完整的。
# Solution 3
library(dplyr)
library(tidyr)
item2 <- c(5, 7, 8)
routelist4 <- routelist %>%
unnest() %>%
group_by(id) %>%
filter(all(item2 %in% node_list)) %>%
filter(node_list %in% item2) %>%
summarise(node_list = toString(node_list)) %>%
filter(node_list == toString(item2))
routelist4
# A tibble: 1 x 2
id node_list
<int> <chr>
1 3 5, 7, 8
使用循环(不优雅)可以在正文中使用以下检查。 它确实考虑到了顺序:
library(data.table)
routelist=data.table(id=c(1:3),node_list=list(c(1:6),c(4:7),c(1:10)))
item<-c(5,8,7)
for(i in 1:nrow(routelist))
{
if(identical(intersect(unlist(routelist[i]$node_list),item),item)){
print(routelist[i])
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.