noname
noname

Reputation: 51

Creating a new column with more rows in a data table

I think I should edit the example since it is misleading. Sorry for the inconvenience :(

The following is an example of the warning that I faced with:

dsf <- data.table(v1=c('a','a','b','b','b','c'),v2=c(3,5,8))
> dsf
   v1 v2
1:  a  3
2:  a  5
3:  b  8
4:  b  3
5:  b  5
6:  c  8

I want to add a new column to produce

   v1 v2  v3
1:  a  3  5 
2:  a  5  7
3:  NA NA 4
4:  b  8  6
5:  b  3  9
6:  b  5  4
7:  NA NA 4
8:  c  8  7
9:  NA NA 9

but I get a warning message like:

In [.data.table(dsf, , :=(v3, c(1:4))) : Supplied 4 items to be assigned to 3 items of column 'v3' (1 unused)

and the data table as:

   v1 v2  v3
1:  a  3  5 
2:  a  5  7
3:  b  8  6
4:  b  3  9
5:  b  5  4
6:  c  8  7

In the original case - that I am working on - I have something like this:

dsf <- dsf[, v3:=f(list(v2)) , by=list(v1)]

The function f creates an extra value.

Upvotes: 2

Views: 88

Answers (3)

noname
noname

Reputation: 51

Maybe, my answer is not good looking, but this is enough for me ... Thanks to Stack Overflow :)

dsf <- data.table(v1=c('a','a','b','b','b','c'),v2=c(3,5,8))

dsf2 <- unique(as.data.frame(dsf[,1]))
dsf2$v2 <- NA

dsf <- rbind(dsf,dsf2)
dsf <- arrange(dsf,v1)
dsf <- dsf[, v3:=c(1:length(v2)), by=list(v1)]
>dsf
   v1 v2 v3
1:  a  3  1
2:  a  5  2
3:  a NA  3
4:  b  8  1
5:  b  3  2
6:  b  5  3
7:  b NA  4
8:  c  8  1
9:  c NA  2

Upvotes: 0

Mike H.
Mike H.

Reputation: 14360

It looks like there is a cbind.fill function from the rowr package that could be useful:

data.table(rowr::cbind.fill(dsf, data.table(v3 = c(1:4)), fill = NA))
#   v1 v2 v3
#1:  a  3  1
#2:  a  5  2
#3:  b  8  3
#4: NA NA  4

Alternatively, you could try merging the two together. Something like:

dsf2 <- dsf[,rows := 1:nrow(dsf)][data.table(v3=c(1:4), rows = 1:4), on = .(rows)][,rows := NULL]
dsf2
#   v1 v2 v3
#1:  a  3  1
#2:  a  5  2
#3:  b  8  3
#4: NA NA  4

Upvotes: 3

CPak
CPak

Reputation: 13581

Use this function

myfun <- function(df, vec) {
    L <- c(as.list(df), v3 = list(vec))
    result <- lapply(L, `length<-`, max(lengths(L)))
    do.call(cbind.data.frame, result)
}

myfun(dsf, 1:4)

    # v1 v2 v3
# 1    a  3  1
# 2    a  5  2
# 3    b  8  3
# 4 <NA> NA  4

Upvotes: 0

Related Questions