Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assigning values in first rows of groups in a data.table

I'd like to assign only those values in the first row of a group in a data.table.

For example (simplified): my data.table is DT with the following content

x v  
1 1  
2 2  
2 3  
3 4  
3 5  
3 6 

The key of DT is x.
I want to address every first line of a group.

This is working fine:DT[, .SD[1], by=x]

x v  
1 1  
2 2  
3 4 

Now, I want to assign only those values of v to 0.

But none of this is working:

DT[, .SD[1], by=x]$v <- 0  
DT[, .SD[1], by=x]$v := 0  
DT[, .SD[1], by=x, v:=0]

I searched the R-help from the package and any links provided but I just can't get it work.
I found notes there saying this would not work but no examples/solutions that helped me out.

I'd be very glad for any suggestions.

(I like this package very much and I don't wanna go back to a data.frame... where I got this working)

edit:

I'd like to have a result like this:

x v  
1 0  
2 0  
2 3  
3 0  
3 5  
3 6  

This is not working:

DT[, .SD[1], by=x] <- DT[, .SD[1], by=x][, v:=0]
like image 330
MDS Avatar asked Nov 19 '14 00:11

MDS


2 Answers

Another option would be:

 DT[,v:={v[1]<-0L;v}, by=x]
 DT
 #  x v
 #1: 1 0
 #2: 2 0
 #3: 2 3
 #4: 3 0
 #5: 3 5
 #6: 3 6

Or

 DT[DT[, .I[1], by=x]$V1, v:=0]
 DT
 #   x v
 #1: 1 0
 #2: 2 0
 #3: 2 3
 #4: 3 0
 #5: 3 5
 #6: 3 6
like image 108
akrun Avatar answered Nov 15 '22 21:11

akrun


With a little help from Roland's solution, it looks like you could do the following. It simply concatenates zero with all the other grouped values of v except the first.

DT[, v := c(0L, v[-1]), by = x]   ## must have the "L" after 0, as 0L

which results in

DT
#    x v
# 1: 1 0
# 2: 2 0
# 3: 2 3
# 4: 3 0
# 5: 3 5
# 6: 3 6

Note: the middle section j of code could also be v := c(integer(1), v[-1])

like image 26
Rich Scriven Avatar answered Nov 15 '22 20:11

Rich Scriven