Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why subsetting with a numeric key doesn't work with data.table

Tags:

r

data.table

I have a table with two numeric rows, one of which is set to key. I would like to subset my data.table by numeric key value, but it doesn't seem to work. When I convert it to character, it works.

Could you help me to understand why is that? I am using data.table 1.8.6.

Thanks a bunch. Here is the test code:

> ID <-c(rep(210, 9), rep(3917,6))
> Count <- c(1,1,0,1,1,1,1,1,1,1,1,1,1,0,1)
> x <- data.table(ID, Count)
> 
> # numeric key doesn't work with i argument
> setkey(ID)
 [1]  210  210  210  210  210  210  210  210  210 3917 3917 3917 3917 3917 3917
> x[210,list(ID, Count)]
   ID Count
1: NA    NA
> 
> # create character key
> x$charID <- as.character(x$ID)
> setkey(x, charID)
> x["210",list(ID, Count)]
   charID  ID Count
1:    210 210     1
2:    210 210     1
3:    210 210     0
4:    210 210     1
5:    210 210     1
6:    210 210     1
7:    210 210     1
8:    210 210     1
9:    210 210     1
like image 776
AdamNYC Avatar asked Dec 02 '12 04:12

AdamNYC


2 Answers

You need to send the numeric key within a data.table. This is done easily using J. Or in a list

Note that you need to specify the data.table when setting the key eg

setkey(x, ID)
x[J(210)]
    ID Count
1: 210     1
2: 210     1
3: 210     0
4: 210     1
5: 210     1
6: 210     1
7: 210     1
8: 210     1
9: 210     1

or

x[list(210)]
    ID Count
1: 210     1
2: 210     1
3: 210     0
4: 210     1
5: 210     1
6: 210     1
7: 210     1
8: 210     1
9: 210     1
like image 174
mnel Avatar answered Oct 17 '22 07:10

mnel


When you ask R for x[210, ] it is looking for the 210th row in x.
If x had 210+ rows, it would return that value (albeit not the row you were intending). Since there is no 210th row, it gives you NA.

When you instead ask for x['210', ], it is looking for the row in x labeled '210'



Try this to see the differences:

 vec <- LETTERS[1:9]
 names(vec) <- c(11:18, 1)

Now compare:

 vec[[11]]
 vec[['11']]


 vec[[1]]
 vec[['1']]
like image 31
Ricardo Saporta Avatar answered Oct 17 '22 05:10

Ricardo Saporta