[datatable-help] Wonder whether there is an easier way to changepart of data.table values
Branson Owen
branson.owen at gmail.com
Fri Jul 30 01:38:16 CEST 2010
Dear Tom,
> [<-.data.table and $<-.data.table both need a bit of work.
>> DT <- data.table(A = c("A", "Z"), Z = 1:10, key = "A")
> You've found the DT$column[index] = new value approach, but if you use that on keys, DT may no longer be sorted right:
>> DT$A[10] <- "A"
>> DT
> A Z
> [1,] A 1
> [2,] A 3
> [3,] A 5
> [4,] A 7
> [5,] A 9
> [6,] Z 2
> [7,] Z 4
> [8,] Z 6
> [9,] Z 8
> [10,] A 100
Yeah, I noticed it. I can even "re-assign" non-integer value to key
column and it won't complain. It checks validity only when
constructing.
> Since we now inherit from data.frames, we can just use [<-.data.frame. It still has the problem that it won't remove the key if the key'd column changes.
>> `[<-.data.table` <- `[<-.data.frame`
>> DT[9,"Z"] <- 22
>> DT
> A Z
> [1,] A 1
> [2,] A 3
> [3,] A 5
> [4,] A 7
> [5,] A 9
> [6,] Z 2
> [7,] Z 4
> [8,] Z 6
> [9,] Z 22
> [10,] A 100
> I'm not sure we want to be able to do DT[select,] <- something.
I think that would ok since we still have some way to achieve it.
> Something like the following will work for a simple select:
>> DT <- data.table(A = c("A", "Z"), Z = 1:10, key = "A")
>> `[<-.data.table` <- `[<-.data.frame`
This is something I dare not do if you don't provide a hint.
>> DT[DT[J("A"), which=TRUE, mult="all"], "Z"] <- 44
>> DT
> A Z
> [1,] A 44
> [2,] A 44
> [3,] A 44
> [4,] A 44
> [5,] A 44
> [6,] Z 2
> [7,] Z 4
> [8,] Z 6
> [9,] Z 8
> [10,] Z 10
>
> The following is equivalent:
>> DT$Z[DT[J("A"), which=TRUE, mult="all"]] <- 55
>> DT
> A Z
> [1,] A 55
> [2,] A 55
> [3,] A 55
> [4,] A 55
> [5,] A 55
> [6,] Z 2
> [7,] Z 4
> [8,] Z 6
> [9,] Z 8
> [10,] Z 10
> I'd prefer to use as much of [<-.data.frame and $<-.data.frame as possible. $<-.data.frame is pretty easy:
>> "$<-.data.table" = function (x, name, value) {
> + res <- `$<-.data.frame`(x, name, value)
> + if (any(name %in% key(x)))
> + key(res) <- NULL
> + res
> + }
>> DT <- data.table(A = c("A", "Z"), Z = 1:10, key = "A")
>> DT$Z[3] <- 33
>> key(DT)
> [1] "A"
>> DT$A[10] <- "A"
>> key(DT)
> NULL
>> DT
> A Z
> [1,] A 1
> [2,] A 3
> [3,] A 33
> [4,] A 7
> [5,] A 9
> [6,] Z 2
> [7,] Z 4
> [8,] Z 6
> [9,] Z 8
> [10,] A 10
> This doesn't allow x to be a data.table-style select. If we want that, I could experiment some.
> [<-.data.table is more challenging, but I could take a shot on a plane ride next week.
Wow, thanks a lot. I hope I can buy you more plane rides for more easy
and cool features. ;-)
Sincerely appreciate your detailed answers!
Best regards,
More information about the datatable-help
mailing list