简体   繁体   中英

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

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.

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM