Skip to content

dt[, uniqueN(col)] does not warn when col is evaluated outside of dt's frame #2186

Description

@mbacou

Hi, the very simple code below returns 20 without warning. This is potentially very error-prone, when the user would normally expect a column named v in dt, but that column is accidentally missing. Not sure if this is intended. Thx!

Tested with data.table 1.10.4.

v <- 1:20
dt <- data.table(a=1:10, b=1:10)
dt[, uniqueN(v)]
# [1] 20

Activity

  1. MichaelChirico commented on Jun 4, 2017

    @MichaelChirico
    Member
  2. mbacou commented on Jun 4, 2017

    @mbacou
    Author

    Yes and no, data.frame would throw an error obviously. Generally, it seems to me that evaluation in ascending scope in j's (and also in by's ?) element is very prone to user errors. Somehow I feel like forcing the user to make an explicit call to an out-of-scope object would be safer (e.g. maybe using something like ..(col) -- but even then, calls like dt[, unique(..(col))] or dt[, sum(..(col))] would make no sense at all, and should throw warnings or errors.

  3. MichaelChirico commented on Jun 4, 2017

    @MichaelChirico
    Member
  4. franknarf1 commented on Jun 4, 2017

    @franknarf1
    Contributor

    I think the proposed inherits = FALSE would cover this #633 and agree it would be nice to have.

    How/why should that differ for a [] call?

    @MichaelChirico Because it protects us from writing j expressions that we don't want to be writing, just like DT[1, v := x ] will protect us if x does not have the right class, etc.

  5. changed the title [-]dt[, uniqueN(col)] does not warm when `col` is evaluated outside of dt's frame[/-] [+]dt[, uniqueN(col)] does not warn when `col` is evaluated outside of dt's frame[/+] on Jun 4, 2017
  6. mbacou commented on Jun 4, 2017

    @mbacou
    Author

    I agree here, inherits = FALSE should be default behavior, with an explicit ..(col1, col2) notation possibly allowed.

    Else in cases as below, a simple warning that "col and by were evaluated outside of dt's scope" would not hurt!

    by <- 1:10
    col <- 1:10
    dt <- data.table(a=1:10, b=1:10)
    dt[, c := sum(a*col), by=by]
    

    Still feel like dt[, c := sum(a*..(col)), by=..(by)] is (ugly) but safer!

  7. arunsrinivasan commented on Jun 29, 2017

    @arunsrinivasan
    Member

    As @franknarf1 pointed out, it's a nice feature to have, and is a dup of #633.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions