Home > Net >  How to apply data table .I function to only specific elements in data table?
How to apply data table .I function to only specific elements in data table?

Time:06-07

Suppose we generate the following data table by running the simple data.table code shown immediately beneath, where the code numbers each element in the data table (Nbr column) and further letter-counts each element of same ID (Class column):

> DT
   ID Nbr Class
1:  A   1     A
2:  A   2     B
3:  B   3     A
4:  C   4     A
5:  D   5     A

DT <- data.table(ID = c("A","A","B","C","D")) 
DT[, c("Nbr", "Class") := .(.I, LETTERS[seq_len(.N)]), by = ID]

How would I modify the above, using data.table, so for example the Class designation ignores all ID elements = B, instead assigning all B elements an NA? I'd rather figure out how to do this in data.table rather than my neophyte reaction of just replacing via base R or using dplyr, since I'm trying to learn how to use data.table. So the results would look like this:

> DT
   ID Nbr Class
1:  A   1     A
2:  A   2     B
3:  B   3     NA
4:  C   4     A
5:  D   5     A

CodePudding user response:

You can use the following code:

library(data.table)
DT[][ID == "B", Class := NA]
DT

Output:

   ID Nbr Class
1:  A   1     A
2:  A   2     B
3:  B   3  <NA>
4:  C   4     A
5:  D   5     A

CodePudding user response:

Modify

DT[, c("Nbr", "Class") := .(.I, LETTERS[seq_len(.N)]), by = ID]

To this

DT[, c("Nbr", "Class") := .(.I, if (ID == "B") NA else LETTERS[seq_len(.N)]), ID]

Full code

DT <- data.table(ID = c("A","A","B","C","D"))
DT[, c("Nbr", "Class") := .(.I, if (ID == "B") NA else LETTERS[seq_len(.N)]), ID]
DT
#>    ID Nbr Class
#> 1:  A   1     A
#> 2:  A   2     B
#> 3:  B   3  <NA>
#> 4:  C   4     A
#> 5:  D   5     A

Second example

DT[, c("Nbr", "Class") := .(.I, if (ID < "E" && ID > "B") NA else LETTERS[seq_len(.N)]), ID]
DT
#>    ID Nbr Class
#> 1:  A   1     A
#> 2:  A   2     B
#> 3:  B   3     A
#> 4:  C   4  <NA>
#> 5:  D   5  <NA>
  • Related