Skip to content

Should setnames() produce duplicate column names without warning? #4044

Open

Description

@sindribaldur
IRIS  <- as.data.table(iris)
setnames(IRIS, "Petal.Length", "Sepal.Length") # No warning (but maybe there should be?)
IRIS[, Sepal.Length] # Only first occurrence is returned
setnames(IRIS, "Sepal.Length", "abc.Length") #  Warning: Only first occurrence is changed

Has been discussed at length here. Without conclusion?

Activity

  1. changed the title [-]behavior in setnames()[/-] [+]Should setnames() produce duplicate column names without warning?[/+] on Nov 13, 2019
  2. jangorecki commented on Nov 29, 2019

    @jangorecki
    Member

    There is a comment

    dups allowed without warning; warn if and when the dup causes an ambiguity

    in

    # if (anyDuplicated(new)) warning("Some duplicates exist in 'new': ", brackify(new[duplicated(new)])) # dups allowed without warning; warn if and when the dup causes an ambiguity

    is there any ambiguity here?
    not in the first expression, second also seems OK, and third... should we rename both columns to a new name?


    rather than micromanaging that here I would prefer to have global option to stop if there are dups in column names, at any stage.

  3. venom1204 commented on Feb 16, 2026

    @venom1204
    Contributor

    Hi @jangorecki,
    I am planning to implement a fix for this issue based on your suggestion to use a centralized approach rather than micromanaging duplicate checks across different functions.
    Proposed Plan:

    • onLoad.R: Register a new global option datatable.warn.duplicate.names (defaulting to FALSE). This ensures backward compatibility for users who rely on the current behavior.
    • utils.R: Add an internal helper warn_if_duplicate_names(). This centralizes the logic so we can easily extend the warning to rbindlist, merge, or setDT in the future without duplicating code.
    • data.table.R: Update setnames() to construct a "preview" of the resulting names and call the utility helper before committing changes.

    if this sounds good i will be happy to proceed with the pr.

  4. ben-schwen commented on Feb 17, 2026

    @ben-schwen
    Member

    My 2 cents on this.

    Maybe we can use something like datatable.unique.names and then options like c("warn", "error", "rename", "off"), where

    • "warn" should return a warning
    • `"error" should return an error
    • "rename" should fix it, e.g. with make.names(, unique=TRUE)
    • "off" should do nothing

    And we can gradually escalate from warning to error and eventually even to rename since one of data.tables "promises" is that it just works

  5. venom1204 commented on Feb 25, 2026

    @venom1204
    Contributor

    Got it, that makes sense. I’ll implement the policy-based approach (off, warn, error, rename) as suggested and open a PR soon. Thanks for the feedback!

    My 2 cents on this.

    Maybe we can use something like datatable.unique.names and then options like c("warn", "error", "rename", "off"), where

    • "warn" should return a warning
    • `"error" should return an error
    • "rename" should fix it, e.g. with make.names(, unique=TRUE)
    • "off" should do nothing

    And we can gradually escalate from warning to error and eventually even to rename since one of data.tables "promises" is that it just works

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions