Skip to content

Commit 2793cea

Browse files
committed
added a helper function 6702
1 parent 8fa0ffb commit 2793cea

File tree

1 file changed

+33
-33
lines changed

1 file changed

+33
-33
lines changed

R/data.table.R

Lines changed: 33 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,35 @@ replace_dot_alias = function(e) {
128128
}
129129
}
130130

131+
.assign_in_parent_exact = function(name, x, env, caller) {
132+
k = eval(name[[2L]], env, env)
133+
if (is.list(k)) {
134+
origj = j = if (name[[1L]] == "$") as.character(name[[3L]]) else eval(name[[3L]], env, env)
135+
136+
if (caller == "[.data.table") {
137+
if (is.character(j)) {
138+
if (length(j) != 1L) stopf("Cannot assign to an under-allocated recursively indexed list -- L[[i]][,:=] syntax is only valid when i is length 1, but its length is %d", length(j))
139+
j = match(j, names(k))
140+
if (is.na(j)) internal_error("item '%s' not found in names of list", origj)
141+
}
142+
} else if (caller == "setDT") {
143+
if (length(j) == 1L) {
144+
if (is.character(j)) {
145+
j = match(j, names(k))
146+
if (is.na(j))
147+
stopf("Item '%s' not found in names of input list", origj)
148+
}
149+
}
150+
}
151+
152+
.Call(Csetlistelt, k, as.integer(j), x)
153+
} else if (is.environment(k) && exists(as.character(name[[3L]]), k)) {
154+
assign(as.character(name[[3L]]), x, k, inherits = FALSE)
155+
} else if (isS4(k)) {
156+
.Call(CsetS4elt, k, as.character(name[[3L]]), x)
157+
}
158+
}
159+
131160
"[.data.table" = function(x, i, j, by, keyby, with=TRUE, nomatch=NA, mult="all", roll=FALSE, rollends=if (roll=="nearest") c(TRUE,TRUE) else if (roll>=0.0) c(FALSE,TRUE) else c(TRUE,FALSE), which=FALSE, .SDcols, verbose=getOption("datatable.verbose"), allow.cartesian=getOption("datatable.allow.cartesian"), drop=NULL, on=NULL, env=NULL, showProgress=getOption("datatable.showProgress", interactive()))
132161
{
133162
# ..selfcount <<- ..selfcount+1 # in dev, we check no self calls, each of which doubles overhead, or could
@@ -1214,21 +1243,8 @@ replace_dot_alias = function(e) {
12141243
setalloccol(x, n, verbose=verbose) # always assigns to calling scope; i.e. this scope
12151244
if (is.name(name)) {
12161245
assign(as.character(name),x,parent.frame(),inherits=TRUE)
1217-
} else if (.is_simple_extraction(name)) { # TODO(#6702): use a helper here as the code is very similar to setDT().
1218-
k = eval(name[[2L]], parent.frame(), parent.frame())
1219-
if (is.list(k)) {
1220-
origj = j = if (name[[1L]] == "$") as.character(name[[3L]]) else eval(name[[3L]], parent.frame(), parent.frame())
1221-
if (is.character(j)) {
1222-
if (length(j)!=1L) stopf("Cannot assign to an under-allocated recursively indexed list -- L[[i]][,:=] syntax is only valid when i is length 1, but its length is %d", length(j))
1223-
j = match(j, names(k))
1224-
if (is.na(j)) internal_error("item '%s' not found in names of list", origj) # nocov
1225-
}
1226-
.Call(Csetlistelt,k,as.integer(j), x)
1227-
} else if (is.environment(k) && exists(as.character(name[[3L]]), k)) {
1228-
assign(as.character(name[[3L]]), x, k, inherits=FALSE)
1229-
} else if (isS4(k)) {
1230-
.Call(CsetS4elt, k, as.character(name[[3L]]), x)
1231-
}
1246+
} else if (.is_simple_extraction(name)) {
1247+
.assign_in_parent_exact(name, x, parent.frame(), caller = "[.data.table")
12321248
} # TO DO: else if env$<- or list$<-
12331249
}
12341250
}
@@ -2971,24 +2987,8 @@ setDT = function(x, keep.rownames=FALSE, key=NULL, check.names=FALSE) {
29712987
if (is.name(name)) {
29722988
name = as.character(name)
29732989
assign(name, x, parent.frame(), inherits=TRUE)
2974-
} else if (.is_simple_extraction(name)) {
2975-
# common case is call from 'lapply()'
2976-
k = eval(name[[2L]], parent.frame(), parent.frame())
2977-
if (is.list(k)) {
2978-
origj = j = if (name[[1L]] == "$") as.character(name[[3L]]) else eval(name[[3L]], parent.frame(), parent.frame())
2979-
if (length(j) == 1L) {
2980-
if (is.character(j)) {
2981-
j = match(j, names(k))
2982-
if (is.na(j))
2983-
stopf("Item '%s' not found in names of input list", origj)
2984-
}
2985-
}
2986-
.Call(Csetlistelt, k, as.integer(j), x)
2987-
} else if (is.environment(k) && exists(as.character(name[[3L]]), k)) {
2988-
assign(as.character(name[[3L]]), x, k, inherits=FALSE)
2989-
} else if (isS4(k)) {
2990-
.Call(CsetS4elt, k, as.character(name[[3L]]), x)
2991-
}
2990+
} else if (.is_simple_extraction(name)) {
2991+
.assign_in_parent_exact(name, x, parent.frame(), caller = "setDT")
29922992
} else if (name %iscall% "get") { # #6725
29932993
# edit 'get(nm, env)' call to be 'assign(nm, x, envir=env)'
29942994
name = match.call(get, name)

0 commit comments

Comments
 (0)