@@ -19,28 +19,98 @@ type_size = function(DT) {
1919}
2020
2121tables = function (mb = type_size , order.col = " NAME" , width = 80L ,
22- env = parent.frame(), silent = FALSE , index = FALSE )
22+ env = parent.frame(), silent = FALSE , index = FALSE ,
23+ list_search = FALSE , list_len_threshold = 100000L )
2324{
2425 # Prints name, size and colnames of all data.tables in the calling environment by default
2526 mb_name = as.character(substitute(mb ))
2627 if (isTRUE(mb )) { mb = type_size ; mb_name = " type_size" }
2728 names = ls(envir = env , all.names = TRUE ) # include "hidden" objects (starting with .)
2829 obj = mget(names , envir = env ) # doesn't copy; mget is ok with ... unlike get, #5197
2930 w = which(vapply_1b(obj , is.data.table ))
30- if (! length(w )) {
31+
32+ list_info = NULL
33+ if (list_search ) {
34+ is_list = vapply_1b(obj , is.list )
35+ dt_mask = logical (length(obj ))
36+ if (length(w )) dt_mask [w ] = TRUE
37+ is_df = vapply_1b(obj , is.data.frame )
38+ list_candidates = which(is_list & ! dt_mask & ! is_df )
39+
40+ if (length(list_candidates )) {
41+ n_extra = 0L
42+ list_locations = vector(" list" , length(list_candidates ))
43+ for (j in seq_along(list_candidates )) {
44+ obj_idx = list_candidates [j ]
45+ L = obj [[obj_idx ]]
46+ if (! is.list(L )) next
47+ lenL = length(L )
48+ if (is.finite(list_len_threshold ) && lenL > list_len_threshold ) next
49+ elem_is_dt = vapply_1b(L , is.data.table )
50+ idx = which(elem_is_dt )
51+ if (length(idx )) {
52+ list_locations [[j ]] = idx
53+ n_extra = n_extra + length(idx )
54+ }
55+ }
56+
57+ if (n_extra ) {
58+ list_info = data.table(NAME = character (n_extra ), NROW = 0L , NCOL = 0L , MB = 0.0 , COLS = list (), KEY = list (), INDICES = list ())
59+ extra_row = 0L
60+ for (j in seq_along(list_candidates )) {
61+ obj_idx = list_candidates [j ]
62+ idx = list_locations [[j ]]
63+ if (is.null(idx ) || ! length(idx )) next
64+ L = obj [[obj_idx ]]
65+ obj_name = names [obj_idx ]
66+ elem_names = names(L )
67+ for (k in idx ) {
68+ extra_row = extra_row + 1L
69+ DT = L [[k ]]
70+ if (! is.null(elem_names ) && length(elem_names ) > = k && nzchar(elem_names [k ])) {
71+ nm = paste0(obj_name , " $" , elem_names [k ])
72+ } else {
73+ nm = paste0(obj_name , " [[" , k , " ]]" )
74+ }
75+ set(list_info , extra_row , " NAME" , nm )
76+ set(list_info , extra_row , " NROW" , nrow(DT ))
77+ set(list_info , extra_row , " NCOL" , ncol(DT ))
78+ if (is.function(mb )) set(list_info , extra_row , " MB" , as.integer(mb(DT )/ 1048576L ))
79+ if (! is.null(tt <- names(DT ))) set(list_info , extra_row , " COLS" , tt )
80+ if (! is.null(tt <- key(DT ))) set(list_info , extra_row , " KEY" , tt )
81+ if (index && ! is.null(tt <- indices(DT ))) set(list_info , extra_row , " INDICES" , tt )
82+ }
83+ }
84+ }
85+ }
86+ }
87+
88+ info = NULL
89+ if (length(w )) {
90+ info = data.table(NAME = names [w ], NROW = 0L , NCOL = 0L , MB = 0.0 , COLS = list (), KEY = list (), INDICES = list ())
91+ for (i in seq_along(w )) { # avoid rbindlist(lapply(DT_names)) in case of a large number of tables
92+ DT = obj [[w [i ]]]
93+ set(info , i , " NROW" , nrow(DT ))
94+ set(info , i , " NCOL" , ncol(DT ))
95+ if (is.function(mb )) set(info , i , " MB" , as.integer(mb(DT )/ 1048576L )) # i.e. 1024**2
96+ if (! is.null(tt <- names(DT ))) set(info , i , " COLS" , tt ) # TODO: don't need these if()s when #5526 is done
97+ if (! is.null(tt <- key(DT ))) set(info , i , " KEY" , tt )
98+ if (index && ! is.null(tt <- indices(DT ))) set(info , i , " INDICES" , tt )
99+ }
100+ }
101+
102+ if (! is.null(list_info ) && nrow(list_info )) {
103+ if (is.null(info )) {
104+ info = list_info
105+ } else {
106+ info = rbind(info , list_info )
107+ }
108+ }
109+
110+ if (is.null(info ) || ! nrow(info )) {
31111 if (! silent ) catf(" No objects of class data.table exist in %s\n " , if (identical(env , .GlobalEnv )) " .GlobalEnv" else format(env ))
32112 return (invisible (data.table(NULL )))
33113 }
34- info = data.table(NAME = names [w ], NROW = 0L , NCOL = 0L , MB = 0.0 , COLS = list (), KEY = list (), INDICES = list ())
35- for (i in seq_along(w )) { # avoid rbindlist(lapply(DT_names)) in case of a large number of tables
36- DT = obj [[w [i ]]]
37- set(info , i , " NROW" , nrow(DT ))
38- set(info , i , " NCOL" , ncol(DT ))
39- if (is.function(mb )) set(info , i , " MB" , as.integer(mb(DT )/ 1048576L )) # i.e. 1024**2
40- if (! is.null(tt <- names(DT ))) set(info , i , " COLS" , tt ) # TODO: don't need these if()s when #5526 is done
41- if (! is.null(tt <- key(DT ))) set(info , i , " KEY" , tt )
42- if (index && ! is.null(tt <- indices(DT ))) set(info , i , " INDICES" , tt )
43- }
44114 if (! is.function(mb )) info [,MB : = NULL ]
45115 if (! index ) info [,INDICES : = NULL ]
46116 if (! order.col %chin % names(info )) stopf(" order.col='%s' not a column name of info" , order.col )
0 commit comments