1
votes

I have previously created a new column of regularly occuring string values to a data.table in R using $<- and c(rep()).

my_data$component <- as.factor(c((rep("Con",1)),(rep("Neu",1)),(rep("Inc",1))))

Since coming back to my scripts to make changes (several months later) as I found an error in my analysis, this code snippet no longer works, and I am rewarded with the following error:

Supplied 3 items to be assigned to 216 items of column 'c'. The RHS length must either be 1 (single values are ok) or match the LHS length exactly. If you wish to 'recycle' the RHS please use rep() explicitly to make this intent clear to readers of your code.

I understand that the solution likely revolves around the := function in data.table, but I am not an R wizard (these scripts were written as a first foray into R, trying to abandon SPSS and Excel as a psychologist). I do not understand how to use rep() on the RHS to achieve the same outcome.

All i would like to have is "con", "neu", and "inc" replicating regularly for the length of my data.table, in a new column. I read in the data.table package pdf that RHS is "A list of replacement values. It is recycled in the usual way to fill the number of rows satisfying i, if any.".

I understood that recycling in the usual way would mean that the recycling occurs until the end of the matrix.

Here's something I've tried, which also gives the same error.

dt <- data.table(A=(1:9))
dt
   A
1: 1
2: 2
3: 3
4: 4
5: 5
6: 6
7: 7
8: 8
9: 9

dt[ , 'c' := .("con","neu","inc")]

I would appreciate any help, because the longer I spend trying to fix this seemingly straightforward issue, that previously worked with less-than-optimal code given data.table's alleged capabilities, the more stupid I feel.

1
Maybe: dt[ , c := rep(c("con","neu","inc"), 3)] ?zx8754

1 Answers

2
votes

To achieve your current task you can do:

library(data.table)
dt <- data.table(A = 1:9)
dt[ , c := rep_len(c("con","neu","inc"), .N)]
dt
   A   c
1: 1 con
2: 2 neu
3: 3 inc
4: 4 con
5: 5 neu
6: 6 inc
7: 7 con
8: 8 neu
9: 9 inc

Note, this is a relatively new feature of data.table (from 07 Apr 2019). The official explanation:

:= no longer recycles length>1 RHS vectors. There was a warning when recycling left a remainder but no warning when the LHS length was an exact multiple of the RHS length (the same behaviour as base R). Consistent feedback for several years has been that recycling is more often a bug. In rare cases where you need to recycle a length>1 vector, please use rep() explicitly. Single values are still recycled silently as before [...]