Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add empty row to data.table if nrow=0?

I can easily add an empty row to a data frame by;

if(nrow(df)==0){ df[nrow(df)+1,] <- NA }

How can I do the same thing to a data.table?

like image 990
Borax Avatar asked Jan 27 '26 06:01

Borax


2 Answers

This seems to work

library(data.table)
# construct an example
dt <- data.table("a", "b")
dt
   V1 V2
1:  a  b
dt <- dt[0L] # could also use dt[-1L] in this case

Note that dt[0L] will always return a data.table with 0 rows but with the same columns as dt (just learned this thanks to the link from Henrik). The data.frame equivalent is dat[0L,].

Check that it has 0 rows. Programatically, you'd use nrow to check as given in the OP.

dt
Empty data.table (0 rows) of 2 cols: V1,V2

Now, fill it

dt[NA]
   V1 V2
1: NA NA

As Henrik points out in the comments below, The i argument in data.table's [ method usually interprets NA as FALSE, which would lead to dropping the row associated with this value. We can see this with

data.table("a", "b")[as.logical(NA)]
Empty data.table (0 rows) of 2 cols: V1,V2

or

data.table("a", "b")[(NA)]
Empty data.table (0 rows) of 2 cols: V1,V2

However, thanks to Henrik's digging through the data.table code, the authors of data.table built in a special case for the exact syntax of dt[NA] to return a single row data.table that is filled with NAs in each column. In this case, they replace the logical NA with the integer version of NA, NA_integer_.

So, in keeping with proper data types,

dt[NA_integer_]

is the preferred syntax. Frank mentions in the comments that it is possible to return the same result by replacing NA_integer_ with any positive integer value, so for example

dt[1L]

will work. Generalizing this insight to any data.table, you can return a single row data.table with NA values with

dt[nrow(dt) + 1L]
like image 58
lmo Avatar answered Jan 29 '26 23:01

lmo


Another option could have been using rbind but then number of column should have been known for it:

library(data.table)

DT <- data.table(id=c(1), Name = c("wow"))

DT2 <- DT[id!=1]

if(nrow(DT2)==0){ 
  DT2 <- rbind(DT2, list(NA, NA))
  }

DT2
#   id Name
#1: NA   NA
like image 31
MKR Avatar answered Jan 29 '26 22:01

MKR



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!