如果R列表元素是向量,如何有效地检查它们的标识?

如果R列表元素是向量,如何有效地检查它们的标识?,r,list,data.table,R,List,Data.table,我有以下R data.table,其中有一列是带有数字元素的列表: library(data.table) dt = data.table( numericcol = rep(42, 8), listcol = list(c(1, 22, 3), 6, 1, 12, c(5, 6, 1123), 3, 42, 1) ) > dt numericcol listcol 1: 42 1,22, 3 2:

我有以下R data.table,其中有一列是带有数字元素的列表:

library(data.table)
dt = data.table(
      numericcol = rep(42, 8),
      listcol = list(c(1, 22, 3), 6, 1, 12, c(5, 6, 1123), 3, 42, 1)
  )
> dt
   numericcol        listcol
1:         42        1,22, 3
2:         42              6
3:         42              1
4:         42             12
5:         42    5,   6,1123
6:         42              3
7:         42             42
8:         42              1
我想创建两列:(1)一列显示每个列表元素的大小;(2)一列布尔值,如果1是元素,则为TRUE,否则为FALSE

以下是输出的外观:

   numericcol        listcol     size    ones
1:         42        1,22, 3     3       TRUE
2:         42              6     1       FALSE
3:         42              1     1       TRUE       
4:         42             12     1       FALSE
5:         42    5,   6,1123     3       FALSE
6:         42              3     1       FALSE
7:         42             42     1       FALSE
8:         42              1     1       TRUE
因此,我知道如何创建列
size
,即

dt[, size:=sapply(dt$listcol, length)]
我知道如何检查元素行是否有1,如果只有一个数字,即

dt[, ones := dt$listcol[dt$listcol == 1] ]
然而,这种假设是错误的。我不知道如何检查具有多个整数的列表列的行是否由1组成


什么是有效的方法?

我们可以通过获取'listcol'的
长度来创建'size',然后循环通过'listcol',检查每个
向量
中的
%是否为1,并将其分配给'one'

dt[, o := sapply(listcol, function(x) 1 %in% x)]
dt
#    numericcol        listcol     o
# 1:         42        1,22, 3  TRUE
# 2:         42              6 FALSE
# 3:         42              1  TRUE
# 4:         42             12 FALSE
# 5:         42    5,   6,1123 FALSE
# 6:         42              3 FALSE
# 7:         42             42 FALSE
# 8:         42              1  TRUE
dt[, size := lengths(listcol)
   ][, ones := unlist(lapply(listcol, function(x) 1 %in% x))]
dt
#   numericcol        listcol size  ones
#1:         42        1,22, 3    3  TRUE
#2:         42              6    1 FALSE
#3:         42              1    1  TRUE
#4:         42             12    1 FALSE
#5:         42    5,   6,1123    3 FALSE
#6:         42              3    1 FALSE
#7:         42             42    1 FALSE
#8:         42              1    1  TRUE

或者另一种选择是使用
map
from
purr
,这样效率更高一些

library(purrr)
dt[, ones := map_lgl(listcol, `%in%`, x = 1)]
如果有并行处理的选项

library(furrr)
plan(multiprocess)
dt[, one := future_map_lgl(listcol, `%in%`, x = 1)]

另外,如果我们打算使用
tidyverse

dt %>%
   mutate(size = lengths(listcol),
          ones = map(listcol, `%in%`, x = 1))
基准
set.seed(24)

dt1我们可以通过获取'listcol'的
长度来创建'size',然后循环通过'listcol',检查每个
向量
中的
%是否为1,并将其分配给'one'

dt[, size := lengths(listcol)
   ][, ones := unlist(lapply(listcol, function(x) 1 %in% x))]
dt
#   numericcol        listcol size  ones
#1:         42        1,22, 3    3  TRUE
#2:         42              6    1 FALSE
#3:         42              1    1  TRUE
#4:         42             12    1 FALSE
#5:         42    5,   6,1123    3 FALSE
#6:         42              3    1 FALSE
#7:         42             42    1 FALSE
#8:         42              1    1  TRUE

或者另一种选择是使用
map
from
purr
,这样效率更高一些

library(purrr)
dt[, ones := map_lgl(listcol, `%in%`, x = 1)]
如果有并行处理的选项

library(furrr)
plan(multiprocess)
dt[, one := future_map_lgl(listcol, `%in%`, x = 1)]

另外,如果我们打算使用
tidyverse

dt %>%
   mutate(size = lengths(listcol),
          ones = map(listcol, `%in%`, x = 1))
基准
set.seed(24)

dt1上面的
sapply()
和上面的
unlist(lapply())
之间有性能差异吗?@ShanZhengYang没有,没有任何速度差异,
sapply
只是更简单、更短。请注意,不需要任何
,我的mistake@ShanZhengYang没有明显的速度差异上面的
sapply()
和上面的
unlist(lapply())
之间有性能差异吗?@ShanZhengYang没有,没有任何速度差异,
sapply
只是更简单、更短而已。请注意,不需要任何
,我的mistake@ShanZhengYang速度不是很快difference@ShanZhengYang我没有对基准测试使用
future\u map\u igl
,因为它取决于内核的数量。@ShanZhengYang我没有对基准测试使用
future\u map\u igl
,因为它取决于内核的数量。