7

I'm new with data.table, and I'm having an issue with this class. I have a table (data1) with 2 columns: Couple and Ratio. Couple is the Key of the data.table. I'm trying to modify a value in the table.

In the following code, cple is an existing value of Couple. When I run it, I get the results shown in the comments:

data1[cple]$Ratio[1]<-0 # I get more than 50 warnings and it doesn't work
data1$Ratio[1]<-0 # It works perfectly (but it's not the same as the above code)

The error seems to have something to do with Keys but I cannot figure out what it means.

Below is an example:

>data1<-data.table(Couple=c("a","a","b","b"),Ratio=1:4)
>data1
   Couple Ratio
1:      a     1
2:      a     2
3:      b     3
4:      b     4

>setkey(data1,Couple)

>data1["a"]$Ratio[1]<-2 #doesn't work warning message

WARNING:
#In `[<-.data.table`(`*tmp*`, "a", value = list(Couple = c("a", "a" :
 # Coerced 'double' RHS to 'integer' to match the column's type; may have truncated precision. Either change the target column to 'double' first (by creating a new 'double' vector length 4 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'integer' (e.g. 1L, NA_[real|integer]_, as.*, etc) to make your intent clear and for speed. Or, set the column type correctly up front when you create the table and stick to it, please.

>data1$Ratio[1]<-2 #works 
>data1
   Couple Ratio
1:      a     2
2:      a     2
3:      b     3
4:      b     4

So I can change the value when accessing the element by its indices, but not when accessing the value by its value. How can I do this?

Josiah Yoder
  • 3,321
  • 4
  • 40
  • 58
Ricky Bobby
  • 7,490
  • 7
  • 46
  • 63
  • 1
    Hi there! Please make your post reproducible. Read the post [**how to make a great reproducible example**](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) on how to do this. Thank you. – Arun Mar 22 '13 at 14:46
  • Try pasting the output from `dput( data1)` if your data.table doesn't have too many rows. (or use `dput( head( data1 ) )` ) if it does. – Simon O'Hanlon Mar 22 '13 at 14:54

2 Answers2

10

you shouldn't use $ with data.table when you ASSIGN data.table is a daughter class of data.frame but it is much better as it can update by reference, without copies. Each time you try to assign with $ like data1$Ratio[1]<-2 it copies the whole table. You should look at the vignette and especially the update := operator. In your case `data1[Couple=='a',Ratio:=c(0L,Ratio[-1])] is what you want.

You might want to read this very good post too.

Community
  • 1
  • 1
statquant
  • 13,672
  • 21
  • 91
  • 162
6

Judging from the first part of your question you want to actually do something like this:

data1[cple,Ratio:=c(0L,Ratio[-1])]

This does a binary search for the value of cple in the data.table key and works then on this subset. An integer zero is combined with the Ratio values except the first and the resulting vector is assigned by reference to Ratio.

Roland
  • 127,288
  • 10
  • 191
  • 288