rafa.pereira
rafa.pereira

Reputation: 13807

Update values using lapply in a data.table conditional to nrow

I want to update the values of a column in a data.table conditional to two other columns in the same table.

This code here works in a way, but I wanted to update the values in my DT instead of returning a list of DTs.

reproducible example:

library(data.table)
library(gtools)

# Create Data Table
  DT <- as.data.table(combinations(3,2,1:3,repeats=TRUE))
  DT[, V3 := 9999 ]

DT
>   V1 V2   V3
>1:  1  1 9999
>2:  1  2 9999
>3:  1  3 9999
>4:  2  2 9999
>5:  2  3 9999
>6:  3  3 9999

My code:

# create function

stationary <- function(i) {DT[i, V3 := if (V1==V2) 0  else  V1+V2 ]}

i <- 1:nrow(DT)

DT <- lapply(i, stationary)  # This returns a list of identical data tables

The result I wanted:

DT
>   V1 V2 V3
>1:  1  1  0
>2:  1  2  3
>3:  1  3  4
>4:  2  2  0
>5:  2  3  5
>6:  3  3  0

Upvotes: 1

Views: 474

Answers (2)

jangorecki
jangorecki

Reputation: 16697

You can use chaining:

library(data.table)
library(gtools) # combinations()
DT <- as.data.table(combinations(3,2,1:3,repeats=TRUE))
DT[, V3 := 9999 ]
DT[V1==V2, V3 := 0
   ][V1!=V2, V3 := as.numeric(V1+V2)
     ][]
#    V1 V2 V3
# 1:  1  1  0
# 2:  1  2  3
# 3:  1  3  4
# 4:  2  2  0
# 5:  2  3  5
# 6:  3  3  0

You can avoid as.numeric call if you stick with integers, so V3 := 9999L and V3 := 0L.

Upvotes: 2

Roland
Roland

Reputation: 132576

I would do this:

DT[, V3 := (V1 + V2) * (V1 != V2)]
#   V1 V2 V3
#1:  1  1  0
#2:  1  2  3
#3:  1  3  4
#4:  2  2  0
#5:  2  3  5
#6:  3  3  0

It's fast and simple.

Upvotes: 5

Related Questions