Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you replace a whole row of a data.table with NA?

Tags:

r

data.table

This seems like something that should be easy but I can't figure it out.

>d=data.table(x=1:5,y=11:15,z=letters[1:5])
>d
   x  y z
1: 1 11 a
2: 2 12 b
3: 3 13 c
4: 4 14 d
5: 5 15 e

Now, I have decided that row 3 is bad data. I want all of those set to NA.

d[3,]<-NA

Warning message: In [<-.data.table(*tmp*, 3, , value = NA) : Coerced 'logical' RHS to 'character' to match the column's type. Either change the target column to 'logical' first (by creating a new 'logical' vector length 5 (nrows of entire table) and assign that; i.e. 'replace' column), or coerce RHS to 'character' (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.

Yet, it seems to work.

> d
    x  y  z
1:  1 11  a
2:  2 12  b
3: NA NA NA
4:  4 14  d
5:  5 15  e

If I convert to data.frame, it also works but without the warning. But then I need to convert back which seems awkward. Is there a better way?

like image 914
user1827975 Avatar asked Mar 21 '13 17:03

user1827975


1 Answers

To set by reference.

DT[rownum, (names(DT)) := lapply(.SD, function(x) {  .x <- x[1]; is.na(.x) <- 1L; .x})]

Or perhaps

DT[rownum, (names(DT)) := lapply(.SD[1,], function(x) { is.na(x) <- 1L; x})]

This will ensure that the correct NA type is created (factor and dates as well)

The second case only indexes once, this may be slightly faster if there are lots of columns in DT or rownum creates a large subgroup of rows.

You could also do (a variant on Roland's solution, but with no copying.

DT[rownum, (names(DT)) := .SD[NA]]
like image 188
mnel Avatar answered Oct 29 '22 11:10

mnel