Skip to content

[R-Forge #2793] Allow subsets of LHS of := #571

Open

Description

@arunsrinivasan

Submitted by: Eduard Antonyan; Assigned to: Eduard Antonyan; R-Forge link

Allow the following syntax:

dt = data.table(a = c(1,1,2,2), b = c(1,2,1,2))
dt[, a[b < 2] := 0]

This is possible to accomplish now using ifelse:

dt[, a := ifelse(b < 2, 0L, a)]

but that's much slower than what potentially could be, because ifelse has to construct vectors and assign values for both b < 2 and b >= 2.

Activity

  1. jangorecki commented on Aug 20, 2014

    @jangorecki
    Member
  2. matthieugomez commented on Sep 1, 2014

    @matthieugomez
    Contributor

    Would not be the same thing as dt[b<2, a := 0] ?
    Maybe it is what is implied by the first post, but, indeed, I think that being able to use relative index for conditions could be nice
    For now, the syntax to do the same is cumbersome.

     DT[DT[,index=.I[expression],by=id]$index,a:=999]
    

    It would be simpler to be able to do things such as

        DT[, a[1] := 999,by=id]
        DT[, a[.N] := 999,by=id]
        DT[, a[which.max(b)]:= 999,by=id]
    
  3. franknarf1 commented on Sep 17, 2015

    @franknarf1
    Contributor

    I think this is a good example (in the comment): http://stackoverflow.com/questions/32638845/replacing-nas-in-dataframe-with-constants-in-another-in-r/32639171#comment53127039_32639171

    Instead of

    DF1[DF2, x := ifelse(is.na(x), i.x, x), on=c("y","z")]
    

    I'd like to do

    DF1[DF2, x[is.na(x)] := i.x, on=c("y","z")]
    
  4. franknarf1 commented on Jan 18, 2016

    @franknarf1
    Contributor

    This is another good example, I think: http://stackoverflow.com/q/34845396

    And another not-bad example: http://stackoverflow.com/q/37862828/

    dat = setDT(structure(list(diameter = c(1L, 1L, 1L, 2L, 2L, 3L), thread = c(4L, 
    6L, 4L, 5L, 7L, 9L), size = c("small", "small", "small", "small", 
    "small", "small")), .Names = c("diameter", "thread", "size"), row.names = c(NA, 
    -6L), class = "data.frame"))
    
    dat[, size := "small"][, size[ thread == max(thread) ] := "large", by = diameter]
    

    And another not-bad example: http://stackoverflow.com/q/38083937/

    library(data.table)
    DT <- data.table(c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2),
                     as.IDate(c("2015-12-31", "2014-12-31", "2013-12-31", "2012-12-31", 
                                "2011-12-31", "2015-12-31", "2014-12-31", "2014-01-25",
                                "2013-01-25", "2012-01-25")))
    setnames(DT, c("id", "date"))
    
    # desired syntax
    DT[, r[month(date) == month(date)[1L]] := year(date) - year(date)[1L], by=id]
    

    And another one: http://stackoverflow.com/q/38910869/

    library(data.table)
    dt_A <- data.table(key1 = LETTERS[1:6], key2 = (1:6), flag=NA_character_ )
    dt_A[4, flag:="exclude"]
    dt_B <- data.table(key1 = LETTERS[3:6], key2 = c(3:5,0L)) 
    
    # desired syntax
    dt_A[dt_B, flag[ flag != "exclude" ] := "include" ]
    
    # In this case, there's an alternative, 
    # but I'm not sure about performance, since it's doing like two joins ...
    
    dt_A[fsetdiff(dt_B, dt_A[flag=="exclude", names(dt_B), with=FALSE]), on=names(dt_B), 
      flag := "include"]
    

    And a bad example: https://stackoverflow.com/a/44525179/ like DT[, x[.N] := sum(v), by=g]

    Another x[.N] := one: https://stackoverflow.com/q/50821561/

  5. DavidArenburg commented on Aug 19, 2016

    @DavidArenburg
    Member

    Another good example of a possibly useful use case on SO http://stackoverflow.com/a/39035748/3001626

    Also, this is labeled as "high" but it is not assigned to any milestone...

  6. MichaelChirico commented on Sep 21, 2016

    @MichaelChirico
    Member

    Agree that the best use cases for this appear to be when combined with a merge in i, or when assigning to the first element of a by group, so that the conditioning is either much harder or impossible to do in i directly. Reverting to an rbindlapply approach to build a DT from scratch for now

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