Skip to content

Commit 7049f9b

Browse files
committed
add setDT, setalloccol
1 parent 738779b commit 7049f9b

22 files changed

+132
-60
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
3535
5. Negative and missing values of `n` argument of adaptive rolling functions trigger an error.
3636
37+
6. `setDT()` and `setalloccol()` gain `duplicateShared` argument (default `TRUE`). When `TRUE`, columns that are shared with other objects are duplicated to avoid unintended modification of the original data, [#2683](https://github.com/Rdatatable/data.table/issues/2683). Previously, shared columns were not duplicated, which could lead to unexpected side effects. `frank()` now uses this internally to preserve names from the input vector and avoid modifying shared vectors, [#4240](https://github.com/Rdatatable/data.table/issues/4240). Thanks to @jangorecki, @BenoitLondon, and @MichaelChirico for the report and @ben-schwen for the fix.
38+
3739
### NOTICE OF INTENDED FUTURE POTENTIAL BREAKING CHANGES
3840
3941
1. `data.table(x=1, <expr>)`, where `<expr>` is an expression resulting in a 1-column matrix without column names, will eventually have names `x` and `V2`, not `x` and `V1`, consistent with `data.table(x=1, <expr>)` where `<expr>` results in an atomic vector, for example `data.table(x=1, cbind(1))` and `data.table(x=1, 1)` will both have columns named `x` and `V2`. In this release, the matrix case continues to be named `V1`, but the new behavior can be activated by setting `options(datatable.old.matrix.autoname)` to `FALSE`. See point 5 under Bug Fixes for more context; this change will provide more internal consistency as well as more consistency with `data.frame()`.

R/as.data.table.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ as.data.table.matrix = function(x, keep.rownames=FALSE, key=NULL, ...) {
6969
for (i in ic) value[[i]] = as.vector(x[, i]) # to drop any row.names that would otherwise be retained inside every column of the data.table
7070
}
7171
col_labels = dimnames(x)[[2L]]
72-
setDT(value)
72+
setDT(value, duplicateShared=FALSE)
7373
if (length(col_labels) == ncols) {
7474
if (any(empty <- !nzchar(col_labels)))
7575
col_labels[empty] = paste0("V", ic[empty])
@@ -233,7 +233,7 @@ as.data.table.list = function(x,
233233
}
234234
}
235235
setattr(ans, "names", vnames)
236-
setDT(ans, key=key) # copy ensured above; also, setDT handles naming
236+
setDT(ans, key=key, duplicateShared=FALSE) # copy ensured above; also, setDT handles naming
237237
if (length(origListNames)==length(ans)) setattr(ans, "names", origListNames) # PR 3854 and tests 2058.15-17
238238
ans
239239
}
@@ -282,7 +282,7 @@ as.data.table.data.frame = function(x, keep.rownames=FALSE, key=NULL, ...) {
282282

283283
# fix for #1078 and #1128, see .resetclass() for explanation.
284284
setattr(ans, "class", .resetclass(x, "data.frame"))
285-
setalloccol(ans)
285+
setalloccol(ans, duplicateShared=FALSE)
286286
setkeyv(ans, key)
287287
ans
288288
}

R/between.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ between = function(x, lower, upper, incbounds=TRUE, NAbounds=TRUE, check=FALSE,
6666
# issue FR #707
6767
# is x[i] found anywhere within [lower, upper] range?
6868
inrange = function(x,lower,upper,incbounds=TRUE) {
69-
query = setDT(list(x=x))
70-
subject = setDT(list(l=lower, u=upper))
69+
query = setDT(list(x=x), duplicateShared=FALSE)
70+
subject = setDT(list(l=lower, u=upper), duplicateShared=FALSE)
7171
ops = if (incbounds) c(4L, 2L) else c(5L, 3L) # >=,<= and >,<
7272
verbose = isTRUE(getOption("datatable.verbose"))
7373
if (verbose) {last.started.at=proc.time();catf("forderv(query) took ... ");flush.console()}
@@ -81,7 +81,7 @@ inrange = function(x,lower,upper,incbounds=TRUE) {
8181
)
8282
xo = ans$xo
8383
options(datatable.verbose=FALSE)
84-
setDT(ans[c("starts", "lens")], key=c("starts", "lens"))
84+
setDT(ans[c("starts", "lens")], key=c("starts", "lens"), duplicateShared=FALSE)
8585
options(datatable.verbose=verbose)
8686
if (verbose) {last.started.at=proc.time();catf("Generating final logical vector ... ");flush.console()}
8787
.Call(Cinrange, idx <- vector("logical", length(x)), xo, ans[["starts"]], ans[["lens"]])

R/data.table.R

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ null.data.table = function() {
3838
ans = list()
3939
setattr(ans,"class",c("data.table","data.frame"))
4040
setattr(ans,"row.names",.set_row_names(0L))
41-
setalloccol(ans)
41+
setalloccol(ans, duplicateShared=FALSE)
4242
}
4343

4444
data.table = function(..., keep.rownames=FALSE, check.names=FALSE, key=NULL, stringsAsFactors=FALSE)
@@ -73,7 +73,7 @@ data.table = function(..., keep.rownames=FALSE, check.names=FALSE, key=NULL, str
7373
for (j in which(vapply_1b(ans, is.character))) set(ans, NULL, j, as_factor(.subset2(ans, j)))
7474
# as_factor is internal function in fread.R currently
7575
}
76-
setalloccol(ans) # returns a NAMED==0 object, unlike data.frame()
76+
setalloccol(ans, duplicateShared=FALSE) # returns a NAMED==0 object, unlike data.frame()
7777
}
7878

7979
replace_dot_alias = function(e) {
@@ -523,7 +523,7 @@ replace_dot_alias = function(e) {
523523
xo = ans$xo ## to make it available for further use.
524524
# temp fix for issue spotted by Jan, test #1653.1. TODO: avoid this
525525
# 'setorder', as there's another 'setorder' in generating 'irows' below...
526-
if (length(ans$indices)) setorder(setDT(ans[1L:3L]), indices)
526+
if (length(ans$indices)) setorder(setDT(ans[1L:3L], duplicateShared=FALSE), indices)
527527
allLen1 = ans$allLen1
528528
f__ = ans$starts
529529
len__ = ans$lens
@@ -575,7 +575,7 @@ replace_dot_alias = function(e) {
575575
}
576576
if (nqbyjoin) {
577577
irows = if (length(xo)) xo[irows] else irows
578-
xo = setorder(setDT(list(indices=rep.int(indices__, len__), irows=irows)))[["irows"]]
578+
xo = setorder(setDT(list(indices=rep.int(indices__, len__), irows=irows), duplicateShared=FALSE))[["irows"]]
579579
ans = .Call(CnqRecreateIndices, xo, len__, indices__, max(indices__), nomatch) # issue#4388 fix
580580
f__ = ans[[1L]]; len__ = ans[[2L]]
581581
allLen1 = FALSE # TODO; should this always be FALSE?
@@ -594,7 +594,7 @@ replace_dot_alias = function(e) {
594594
irows = xo[irows] # TO DO: fsort here?
595595
if (mult=="all" && !allGrp1) { # following #1991 fix, !allGrp1 will always be TRUE. TODO: revisit.
596596
if (verbose) {last.started.at=proc.time();catf("Reorder irows for 'mult==\"all\" && !allGrp1' ... ");flush.console()}
597-
irows = setorder(setDT(list(indices=rep.int(indices__, len__), irows=irows)))[["irows"]]
597+
irows = setorder(setDT(list(indices=rep.int(indices__, len__), irows=irows), duplicateShared=FALSE))[["irows"]]
598598
if (verbose) {cat(timetaken(last.started.at),"\n"); flush.console()}
599599
}
600600
}
@@ -1245,7 +1245,7 @@ replace_dot_alias = function(e) {
12451245
# Note also that this growing will happen for missing columns assigned NULL, too. But so rare, we
12461246
# don't mind.
12471247
}
1248-
setalloccol(x, n, verbose=verbose) # always assigns to calling scope; i.e. this scope
1248+
setalloccol(x, n, verbose=verbose, duplicateShared=FALSE) # always assigns to calling scope; i.e. this scope
12491249
if (is.name(name)) {
12501250
assign(as.character(name),x,parent.frame(),inherits=TRUE)
12511251
} else if (.is_simple_extraction(name)) {
@@ -1352,7 +1352,7 @@ replace_dot_alias = function(e) {
13521352
setattr(ans, "sorted", .join_result_key(x, i, ans, if (!missing(on)) names(on), ansvars, leftcols, rightcols, names_i, irows, roll))
13531353
setattr(ans, "class", class(x)) # retain class that inherits from data.table, #64
13541354
setattr(ans, "row.names", .set_row_names(length(ans[[1L]])))
1355-
setalloccol(ans)
1355+
setalloccol(ans, duplicateShared=FALSE)
13561356
}
13571357
if (!with || missing(j)) return(ans)
13581358
if (!is.data.table(ans)) setattr(ans, "class", c("data.table","data.frame")) # DF |> DT(,.SD[...]) .SD should be data.table, test 2212.013
@@ -2018,7 +2018,7 @@ replace_dot_alias = function(e) {
20182018
} else if (.by_result_is_keyable(x, keyby, bysameorder, byjoin, allbyvars, bysub)) {
20192019
setattr(ans, "sorted", names(ans)[seq_along(grpcols)])
20202020
}
2021-
setalloccol(ans) # TODO: overallocate in dogroups in the first place and remove this line
2021+
setalloccol(ans, duplicateShared=FALSE) # TODO: overallocate in dogroups in the first place and remove this line
20222022
}
20232023

20242024
# can the specified merge of x and i be marked as sorted? return the columns for which this is true, otherwise NULL
@@ -2242,7 +2242,7 @@ tail.data.table = function(x, n=6L, ...) {
22422242
if (!cedta()) {
22432243
x = if (nargs()<4L) `[<-.data.frame`(x, i, value=value)
22442244
else `[<-.data.frame`(x, i, j, value)
2245-
return(setalloccol(x)) # over-allocate (again). Avoid all this by using :=.
2245+
return(setalloccol(x, duplicateShared=FALSE)) # over-allocate (again). Avoid all this by using :=.
22462246
}
22472247
# TO DO: warningf("Please use DT[i,j:=value] syntax instead of DT[i,j]<-value, for efficiency. See ?':='")
22482248
if (!missing(i)) {
@@ -2251,7 +2251,7 @@ tail.data.table = function(x, n=6L, ...) {
22512251
if (is.matrix(i)) {
22522252
if (!missing(j)) stopf("When i is a matrix in DT[i]<-value syntax, it doesn't make sense to provide j")
22532253
x = `[<-.data.frame`(x, i, value=value)
2254-
return(setalloccol(x))
2254+
return(setalloccol(x, duplicateShared=FALSE))
22552255
}
22562256
i = x[i, which=TRUE]
22572257
# Tried adding ... after value above, and passing ... in here (e.g. for mult="first") but R CMD check
@@ -2284,11 +2284,11 @@ tail.data.table = function(x, n=6L, ...) {
22842284
reinstatekey=key(x)
22852285
}
22862286
if (!selfrefok(x) || truelength(x) < ncol(x)+length(newnames)) {
2287-
x = setalloccol(x, length(x)+length(newnames)) # because [<- copies via *tmp* and main/duplicate.c copies at length but copies truelength over too
2287+
x = setalloccol(x, length(x)+length(newnames), duplicateShared=FALSE) # because [<- copies via *tmp* and main/duplicate.c copies at length but copies truelength over too
22882288
# search for one other .Call to assign in [.data.table to see how it differs
22892289
}
22902290
x = .Call(Cassign,copy(x),i,cols,newnames,value) # From 3.1.0, DF[2,"b"] = 7 no longer copies DF$a (so in this [<-.data.table method we need to copy)
2291-
setalloccol(x) # can maybe avoid this realloc, but this is (slow) [<- anyway, so just be safe.
2291+
setalloccol(x, duplicateShared=FALSE) # can maybe avoid this realloc, but this is (slow) [<- anyway, so just be safe.
22922292
if (length(reinstatekey)) setkeyv(x,reinstatekey)
22932293
invisible(x)
22942294
# no copy at all if user calls directly; i.e. `[<-.data.table`(x,i,j,value)
@@ -2302,7 +2302,7 @@ tail.data.table = function(x, n=6L, ...) {
23022302
"$<-.data.table" = function(x, name, value) {
23032303
if (!cedta()) {
23042304
ans = `$<-.data.frame`(x, name, value) # nocov
2305-
return(setalloccol(ans)) # nocov. over-allocate (again)
2305+
return(setalloccol(ans, duplicateShared=FALSE)) # nocov. over-allocate (again)
23062306
}
23072307
x = copy(x)
23082308
set(x,j=name,value=value) # important i is missing here
@@ -2359,7 +2359,7 @@ dimnames.data.table = function(x) {
23592359
setattr(x,"names",NULL) # e.g. plyr::melt() calls base::unname()
23602360
else {
23612361
setnames(x,value)
2362-
setalloccol(x)
2362+
setalloccol(x, duplicateShared=FALSE)
23632363
}
23642364
x # this returned value is now shallow copied by R 3.1.0 via *tmp*. A very welcome change.
23652365
}
@@ -2601,7 +2601,7 @@ copy = function(x) {
26012601
reallocate = function(y) {
26022602
if (is.data.table(y)) {
26032603
.Call(C_unlock, y)
2604-
setalloccol(y)
2604+
setalloccol(y, duplicateShared=FALSE)
26052605
} else if (is.list(y)) {
26062606
oldClass = class(y)
26072607
setattr(y, 'class', NULL) # otherwise [[.person method (which returns itself) results in infinite recursion, #4620
@@ -2666,11 +2666,11 @@ shallow = function(x, cols=NULL) {
26662666
ans
26672667
}
26682668

2669-
setalloccol = alloc.col = function(DT, n=getOption("datatable.alloccol"), verbose=getOption("datatable.verbose"))
2669+
setalloccol = alloc.col = function(DT, n=getOption("datatable.alloccol"), verbose=getOption("datatable.verbose"), duplicateShared=TRUE)
26702670
{
26712671
name = substitute(DT)
26722672
if (identical(name, quote(`*tmp*`))) stopf("setalloccol attempting to modify `*tmp*`")
2673-
ans = .Call(Calloccolwrapper, DT, eval(n), verbose)
2673+
ans = .Call(Calloccolwrapper, DT, eval(n), verbose, duplicateShared)
26742674
if (is.name(name)) {
26752675
name = as.character(name)
26762676
assign(name,ans,parent.frame(),inherits=TRUE)
@@ -2875,7 +2875,7 @@ rbindlist = function(l, use.names="check", fill=FALSE, idcol=NULL, ignore.attr=F
28752875
}
28762876
ans = .Call(Crbindlist, l, use.names, fill, idcol, ignore.attr)
28772877
if (!length(ans)) return(null.data.table())
2878-
setDT(ans)[]
2878+
setDT(ans, duplicateShared=FALSE)[]
28792879
}
28802880

28812881
vecseq = function(x,y,clamp) .Call(Cvecseq,x,y,clamp)
@@ -2953,7 +2953,7 @@ setDF = function(x, rownames=NULL) {
29532953
invisible(x)
29542954
}
29552955

2956-
setDT = function(x, keep.rownames=FALSE, key=NULL, check.names=FALSE) {
2956+
setDT = function(x, keep.rownames=FALSE, key=NULL, check.names=FALSE, duplicateShared=TRUE) {
29572957
name = substitute(x)
29582958
if (is.name(name)) {
29592959
home = function(x, env) {
@@ -2968,12 +2968,14 @@ setDT = function(x, keep.rownames=FALSE, key=NULL, check.names=FALSE) {
29682968
stopf("Cannot convert '%1$s' to data.table by reference because binding is locked. It is very likely that '%1$s' resides within a package (or an environment) that is locked to prevent modifying its variable bindings. Try copying the object to your current environment, ex: var <- copy(var) and then using setDT again.", cname)
29692969
}
29702970
}
2971+
if (!isTRUEorFALSE(duplicateShared))
2972+
stopf("'%s' must be TRUE or FALSE", "duplicateShared")
29712973
if (is.data.table(x)) {
29722974
# fix for #1078 and #1128, see .resetclass() for explanation.
29732975
setattr(x, 'class', .resetclass(x, 'data.table'))
29742976
if (!missing(key)) setkeyv(x, key) # fix for #1169
29752977
if (check.names) setattr(x, "names", make.names(names(x), unique=TRUE))
2976-
if (selfrefok(x) > 0L) return(invisible(x)) else setalloccol(x)
2978+
if (selfrefok(x) > 0L) return(invisible(x)) else setalloccol(x, duplicateShared=duplicateShared)
29772979
} else if (is.data.frame(x)) {
29782980
# check no matrix-like columns, #3760. Allow a single list(matrix) is unambiguous and depended on by some revdeps, #3581
29792981
# for performance, only warn on the first such column, #5426
@@ -2988,8 +2990,9 @@ setDT = function(x, keep.rownames=FALSE, key=NULL, check.names=FALSE) {
29882990
setattr(x, "row.names", .set_row_names(nrow(x)))
29892991
if (check.names) setattr(x, "names", make.names(names(x), unique=TRUE))
29902992
# fix for #1078 and #1128, see .resetclass() for explanation.
2991-
setattr(x, "class", .resetclass(x, 'data.frame'))
2992-
setalloccol(x)
2993+
setalloccol(x, duplicateShared=duplicateShared)
2994+
setattr(x, "class", .resetclass(x, 'data.frame')) # selfrek not ok after setattr class
2995+
setalloccol(x, duplicateShared=duplicateShared)
29932996
if (!is.null(rn)) {
29942997
nm = c(if (is.character(keep.rownames)) keep.rownames[1L] else "rn", names(x))
29952998
x[, (nm[1L]) := rn]
@@ -3017,7 +3020,7 @@ setDT = function(x, keep.rownames=FALSE, key=NULL, check.names=FALSE) {
30173020
}
30183021
setattr(x, "row.names", .set_row_names(nrow))
30193022
setattr(x, "class", c("data.table", "data.frame"))
3020-
setalloccol(x)
3023+
setalloccol(x, duplicateShared = duplicateShared)
30213024
} else {
30223025
stopf("Argument 'x' to 'setDT' should be a 'list', 'data.frame' or 'data.table'")
30233026
}

R/fcast.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
162162
if (any(vapply_1b(dat[varnames], is.list))) {
163163
stopf("Columns specified in formula can not be of type list")
164164
}
165-
setDT(dat)
165+
setDT(dat, duplicateShared=FALSE)
166166

167167
m = as.list(match.call()[-1L])
168168
subset = m[["subset"]][[2L]]
@@ -214,7 +214,7 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
214214
lhs = shallow(dat, lhsnames); rhs = shallow(dat, rhsnames); val = shallow(dat, valnames)
215215
# handle drop=TRUE/FALSE - Update: Logic moved to R, AND faster than previous version. Take that... old me :-).
216216
if (all(drop)) {
217-
map = setDT(lapply(list(lhsnames, rhsnames), function(cols) frankv(dat, cols=cols, ties.method="dense", na.last=FALSE))) # #2202 fix
217+
map = setDT(lapply(list(lhsnames, rhsnames), function(cols) frankv(dat, cols=cols, ties.method="dense", na.last=FALSE)), duplicateShared=FALSE) # #2202 fix
218218
maporder = lapply(map, order_)
219219
mapunique = lapply(seq_along(map), function(i) .Call(CsubsetVector, map[[i]], maporder[[i]]))
220220
lhs = .Call(CsubsetDT, lhs, maporder[[1L]], seq_along(lhs))
@@ -225,7 +225,7 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
225225
map = vector("list", 2L)
226226
.Call(Csetlistelt, map, 1L, lhs_[lhs, which=TRUE])
227227
.Call(Csetlistelt, map, 2L, rhs_[rhs, which=TRUE])
228-
setDT(map)
228+
setDT(map, duplicateShared=FALSE)
229229
mapunique = vector("list", 2L)
230230
.Call(Csetlistelt, mapunique, 1L, seq_len(nrow(lhs_)))
231231
.Call(Csetlistelt, mapunique, 2L, seq_len(nrow(rhs_)))
@@ -245,7 +245,7 @@ dcast.data.table = function(data, formula, fun.aggregate = NULL, sep = "_", ...,
245245
else c(CJ(valnames, allcols, sorted=FALSE), sep=sep))
246246
# removed 'setcolorder()' here, #1153
247247
setattr(ans, 'names', c(lhsnames, allcols))
248-
setDT(ans)
248+
setDT(ans, duplicateShared=FALSE)
249249
setattr(ans, 'sorted', lhsnames)
250250
ans
251251
}

R/fmelt.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ melt.data.table = function(data, id.vars, measure.vars, variable.name = "variabl
216216
as.logical(variable.factor), as.logical(value.factor),
217217
variable.name, value.name, as.logical(na.rm),
218218
as.logical(verbose))
219-
setDT(ans)
219+
setDT(ans, duplicateShared=FALSE)
220220
if (anyDuplicated(names(ans))) {
221221
catf("Duplicate column names found in molten data.table. Setting unique names using 'make.names'\n")
222222
setnames(ans, make.unique(names(ans)))

R/foverlaps.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ foverlaps = function(x, y, by.x=key(x) %||% key(y), by.y=key(y), maxgap=0L, mino
172172
}
173173
# nocov end
174174

175-
setDT(olaps)
175+
setDT(olaps, duplicateShared=FALSE)
176176
setnames(olaps, c("xid", "yid"))
177177
yid = NULL # for 'no visible binding for global variable' from R CMD check on i clauses below
178178

R/frank.R

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ frankv = function(x, cols=seq_along(x), order=1L, na.last=TRUE, ties.method=c("a
55
warningf("length(na.last) > 1, only the first element will be used")
66
na.last = na.last[1L]
77
}
8+
input_names = NULL
89
keep = (na.last == "keep")
910
na.last = as.logical(na.last)
1011
as_list = function(x) {
@@ -16,6 +17,7 @@ frankv = function(x, cols=seq_along(x), order=1L, na.last=TRUE, ties.method=c("a
1617
if (!missing(cols) && !is.null(cols))
1718
stopf("x is a single vector, non-NULL 'cols' doesn't make sense")
1819
cols = 1L
20+
input_names = names(x)
1921
x = as_list(x)
2022
} else {
2123
cols = colnamesInt(x, cols, check_dups=TRUE)
@@ -24,7 +26,7 @@ frankv = function(x, cols=seq_along(x), order=1L, na.last=TRUE, ties.method=c("a
2426
}
2527
# need to unlock for #4429
2628
x = .shallow(x, cols, unlock = TRUE) # shallow copy even if list..
27-
setDT(x)
29+
setDT(x, duplicateShared=TRUE)
2830
cols = seq_along(cols)
2931
if (is.na(na.last)) {
3032
if ("..na_prefix.." %chin% names(x))
@@ -66,10 +68,15 @@ frankv = function(x, cols=seq_along(x), order=1L, na.last=TRUE, ties.method=c("a
6668
# take care of na.last="keep"
6769
V1 = NULL # for R CMD CHECK warning
6870
if (isTRUE(keep)) {
69-
ans = (setDT(as_list(ans))[which_(nas, TRUE), V1 := NA])[[1L]]
71+
ans = (setDT(as_list(ans), duplicateShared=TRUE)[which_(nas, TRUE), V1 := NA])[[1L]]
7072
} else if (is.na(na.last)) {
71-
ans = ans[which_(nas, FALSE)]
73+
idx = which_(nas, FALSE)
74+
if (!is.null(input_names))
75+
input_names = input_names[idx]
76+
ans = ans[idx]
7277
}
78+
if (!is.null(input_names))
79+
names(ans) = input_names
7380
ans
7481
}
7582

R/fread.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ yaml=FALSE, tmpdir=tempdir(), tz="UTC")
301301

302302
if (isTRUE(data.table)) {
303303
setattr(ans, "class", c("data.table", "data.frame"))
304-
setalloccol(ans)
304+
setalloccol(ans, duplicateShared=FALSE)
305305
} else {
306306
setattr(ans, "class", "data.frame")
307307
}

R/frollapply.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ frollapply = function(X, N, FUN, ..., by.column=TRUE, fill=NA, align=c("right","
265265
} else {
266266
rev.d = function(d) {
267267
l = lapply(d, rev)
268-
if (is.data.table(d)) setDT(l) else if (is.data.frame(d)) setDF(l) else l
268+
if (is.data.table(d)) setDT(l, duplicateShared=FALSE) else if (is.data.frame(d)) setDF(l) else l
269269
}
270270
X = lapply(X, rev.d)
271271
}

0 commit comments

Comments
 (0)