Skip to content

data.table(keep.rownames = TRUE) should preserve names from vectors #1916

Description

@richierocks

data.frames will form row names from the names of vector inputs.

data.frame(
  x = setNames((1:12) ^ 3, month.abb)
)

I expected data.table to do something similar when keep.rownames = TRUE. That is I expected that these two pieces of code would be equivalent:

data.table(
  x = setNames((1:12) ^ 3, month.abb),
  keep.rownames = TRUE
)

data.table(
  rn = month.abb,
  x = (1:12) ^ 3
)

Currently keep.rownames = TRUE seems to only apply to matrix or data.frame inputs, rather than vectors. Changing the behavior so that keep.rownames = TRUE mimics data.frame behavior seems desirable.

Activity

  1. MichaelChirico commented on Nov 17, 2016

    @MichaelChirico
    Member

    I think this is very close in intent to #1244.

    For the record, data.frame only assigns the names of the first passed vector:

    data.frame(
      x = setNames((1:3) ^ 3, month.abb[1:3]),
      y = setNames(nm = 3:1)
    )
    #      x y
    # Jan  1 3
    # Feb  8 2
    # Mar 27 1
    
  2. richierocks commented on Nov 17, 2016

    @richierocks
    Author

    @MichaelChirico Thanks, I hadn't spotted that issue.

    FYI, data.frame takes the row names from the first vector that is named. For example, if the first vector isn't named but the second one is, it takes names from the second one.

    data.frame(
        x = (1:3) ^ 3,
        y = setNames(nm = 3:1)
    )
  3. Mukulyadav2004 commented on Jul 6, 2025

    @Mukulyadav2004
    Contributor

    Hi @MichaelChirico @tdhock ,
    Can I work on this. My approach is simply to mimic data.frame() behavior by detecting the first named vector in as.data.table.list() and extracting its names as a rownames column when keep.rownames = TRUE.
    So in as.data.table.R add logic to-

    • find the first named atomic vector
    • extract and remove its names
    • then prepend names as first column

    Does this seems right to you?

  4. MichaelChirico commented on Jul 6, 2025

    @MichaelChirico
    Member

    Thanks Mukul, I think for this feature, consistency with data.frame is important, so with that in mind I'd

    • Study the behavior of data.frame() here to be sure you've understood how/when row names are extracted from its inputs.
    • Do the same for as.data.frame() methods, e.g. as.data.frame.matrix(), to see if this feature should also extend to e.g. as.data.table.list() (which is the workhorses behind data.table()). That's important for knowing where to apply the fix -- in the as.data.table method, or just in data.table() itself.
    • Keep in mind keep.rownames="col" typically creates the column col to store the row names, which we should support for consistency.
  5. Mukulyadav2004 commented on Jul 7, 2025

    @Mukulyadav2004
    Contributor

    Thanks @MichaelChirico
    I find that as.data.frame.list() handles the extraction for data.frame to automatically extract names from the first named vector as row names.
    And also both data.frame(x = named_vector) and as.data.frame(list(x = named_vector)) produce identical results so I believe fix belongs to as.data.table.lists() as data.table() calls as.data.table.list() and also as.data.table() methods also route through as.data.table.list().
    In Current matrix implementation keep.rownames=TRUE creates "rn" and keep.rownames="col" creates "col" so I will follow the exact pattern.
    If this seems right, can I open a PR?

  6. MichaelChirico commented on Jul 7, 2025

    @MichaelChirico
    Member

    Great start, I think you're ready to proceed to PR.

    Keep in mind OP's follow-up comment too:

    FYI, data.frame takes the row names from the first vector that is named. For example, if the first vector isn't named but the second one is, it takes names from the second one.

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