@@ -129,31 +129,24 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
129129 stopf(" Argument 'value.var.in.dots' should be logical TRUE/FALSE" )
130130 if (! isTRUEorFALSE(value.var.in.LHSdots ) || ! isTRUEorFALSE(value.var.in.RHSdots ))
131131 stopf(" Arguments 'value.var.in.LHSdots', 'value.var.in.RHSdots' should be logical TRUE/FALSE" )
132-
133132 handle_empty_strings = function (names ) {
134133 names [names == " " ] = " empty_string"
135134 names
136135 }
137-
138136 ensure_unique_names = function (names ) {
139137 if (any(duplicated(names ))) {
140138 names = make.unique(names , sep = " _" )
141139 }
142140 names
143141 }
144-
145142 if (missing(value.var ) && ! missing(fun.aggregate ) && identical(fun.aggregate , length ))
146143 value.var = names(data )[ncol(data )]
147-
148144 lvals = value_vars(value.var , names(data ))
149145 valnames = unique(unlist(lvals ))
150-
151146 valnames = handle_empty_strings(valnames )
152147 valnames = ensure_unique_names(valnames )
153-
154148 lvars = check_formula(formula , names(data ), valnames , value.var.in.LHSdots , value.var.in.RHSdots )
155149 lvars = lapply(lvars , function (x ) if (length(x )) x else quote(`.` ))
156-
157150 allcols = c(unlist(lvars ), lapply(valnames , as.name ))
158151 dat = vector(" list" , length(allcols ))
159152 for (i in seq_along(allcols )) {
@@ -162,34 +155,28 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
162155 if (is.function(dat [[i ]]))
163156 stopf(" Column [%s] not found or of unknown type." , deparse(x ))
164157 }
165-
166158 setattr(lvars , ' names' , c(" lhs" , " rhs" ))
167-
168159 varnames = make.unique(vapply_1c(unlist(lvars ), all.vars , max.names = 1L ), sep = sep )
169160 dupidx = which(valnames %chin % varnames )
170161 if (length(dupidx )) {
171162 dups = valnames [dupidx ]
172163 valnames = tail(make.unique(c(varnames , valnames )), - length(varnames ))
173164 lvals = lapply(lvals , function (x ) { x [x %chin % dups ] = valnames [dupidx ]; x })
174165 }
175-
176166 lhsnames = head(varnames , length(lvars $ lhs ))
177167 rhsnames = tail(varnames , - length(lvars $ lhs ))
178168 setattr(dat , ' names' , c(varnames , valnames ))
179-
180169 if (any(vapply_1b(dat [varnames ], is.list ))) {
181170 stopf(" Columns specified in formula can not be of type list" )
182171 }
183172 setDT(dat )
184-
185173 m = as.list(match.call()[- 1L ])
186174 subset = m [[" subset" ]][[2L ]]
187175 if (! is.null(subset )) {
188176 if (is.name(subset )) subset = as.call(list (quote(`(` ), subset ))
189- idx = which(eval(subset , data , parent.frame()))
177+ idx = which(eval(subset , data , parent.frame())) # any advantage thro' secondary keys?
190178 dat = .Call(CsubsetDT , dat , idx , seq_along(dat ))
191179 }
192-
193180 fun.call = m [[" fun.aggregate" ]]
194181 if (is.null(fun.call )) {
195182 oo = forderv(dat , by = varnames , retGrp = TRUE )
@@ -198,7 +185,6 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
198185 fun.call = quote(length )
199186 }
200187 }
201-
202188 dat_for_default_fill = dat
203189 run_agg_funs = ! is.null(fun.call )
204190 if (run_agg_funs ) {
@@ -216,14 +202,12 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
216202 }
217203 dat = dat [, maybe_err(eval(fun.call )), by = c(varnames )]
218204 }
219-
220205 order_ = function (x ) {
221206 o = forderv(x , retGrp = TRUE , sort = TRUE )
222207 idx = attr(o , ' starts' , exact = TRUE )
223208 if (! length(o )) o = seq_along(x )
224209 o [idx ]
225210 }
226-
227211 cj_uniq = function (DT ) {
228212 do.call(CJ , lapply(DT , function (x )
229213 if (is.factor(x )) {
@@ -232,15 +216,11 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
232216 setattr(xint , ' class' , class(x ))
233217 } else .Call(CsubsetVector , x , order_(x ))
234218 ))}
235-
236219 valnames = setdiff(names(dat ), varnames )
237-
238220 if (! is.null(fun.call ) || ! is.null(subset ))
239221 setkeyv(dat , varnames )
240-
241222 if (length(rhsnames )) {
242223 lhs = shallow(dat , lhsnames ); rhs = shallow(dat , rhsnames ); val = shallow(dat , valnames )
243-
244224 if (all(drop )) {
245225 map = setDT(lapply(list (lhsnames , rhsnames ), function (cols ) frankv(dat , cols = cols , ties.method = " dense" , na.last = FALSE )))
246226 maporder = lapply(map , order_ )
@@ -259,28 +239,23 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
259239 .Call(Csetlistelt , mapunique , 2L , seq_len(nrow(rhs_ )))
260240 lhs = lhs_ ; rhs = rhs_
261241 }
262-
263242 maplen = lengths(mapunique )
264243 idx = do.call(CJ , mapunique )[map , ' I' : = .I ][[" I" ]]
265244 some_fill = anyNA(idx )
266245 fill.default = if (run_agg_funs && is.null(fill ) && some_fill ) dat_for_default_fill [, maybe_err(eval(fun.call ))]
267246 if (run_agg_funs && is.null(fill ) && some_fill ) {
268247 fill.default = dat_for_default_fill [0L ][, maybe_err(eval(fun.call ))]
269248 }
270-
271249 ans = .Call(Cfcast , lhs , val , maplen [[1L ]], maplen [[2L ]], idx , fill , fill.default , is.null(fun.call ), some_fill )
272250 allcols = do.call(paste , c(rhs , sep = sep ))
273251 if (length(valnames ) > 1L )
274252 allcols = do.call(paste , if (identical(" ." , allcols )) list (valnames , sep = sep )
275253 else c(CJ(valnames , allcols , sorted = FALSE ), sep = sep ))
276-
277254 if (length(lhsnames ) + length(allcols ) != length(ans )) {
278255 stopf(" Length mismatch: 'names' attribute [%d] must match the vector length [%d]." , length(lhsnames ) + length(allcols ), length(ans ))
279256 }
280-
281257 setattr(ans , ' names' , c(lhsnames , allcols ))
282258 setDT(ans ); setattr(ans , ' sorted' , lhsnames )
283259 } else internal_error(" empty rhsnames" )
284-
285260 return (ans )
286261}
0 commit comments