Альтернатива plyr :: mapvalues ​​в data.table - PullRequest
1 голос
/ 12 ноября 2019

Я ищу удобочитаемую альтернативу plyr::mapvalues в data.table.

Например, в plyr::mapvalues, если я хочу изменить значения carb в mtcars наtype1, type2, type3, я бы сделал что-то вроде этого:

library(tidyverse)

mtcars %>% 
  mutate(carb = plyr::mapvalues(
    carb,
    from = c("1", "2", "3", "4", "6", "8"),
    to = c("type1", "type1", "type2", "type2", "type3", "type3")))

Чтобы получить то же самое в data.table, я бы сделал это так, что не похоже на обычный метод:

library(data.table)

dt <- data.table(mtcars)
dt$carb <- as.character(dt$carb)

dt[which(carb %in% c("1", "2")), 
   carb := "type1"]

dt[which(carb %in% c("3", "4")), 
   carb := "type2"]

dt[which(carb %in% c("6", "8")), 
   carb := "type3"]

Можно ли изменить все значения в одном условии (dt[...])?

Ответы [ 3 ]

5 голосов
/ 12 ноября 2019

Использование base::factor - самый простой метод:

library(data.table)

setDT(mtcars)[, carb := factor(carb, 
                                levels = c("1", "2", "3", 
                                           "4", "6", "8"),
                                labels = c("type1", "type1",
                                           "type2", "type2", 
                                           "type3", "type3"))][]

#>      mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#>  1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4 type2
#>  2: 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4 type2
#>  3: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4 type1
#>  4: 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3 type1
#>  5: 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3 type1
#>  6: 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3 type1
#>  7: 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3 type2
#>  8: 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4 type1
#>  9: 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4 type1
## ...
5 голосов
/ 12 ноября 2019

Я удивлен, что никто не предложил просто сделать это как объединение:

dt[
  .(carb=c("1","2","3","4","6","8"), type=rep(c("type1","type2","type3"),each=2)),
  on="carb",
  type := i.type
]

Это также легко расширяется на сопоставление с несколькими переменными.

3 голосов
/ 12 ноября 2019

Как насчет использования match

dt[, carb := rep(paste0("Type", 1:3), each = 2)[match(carb, c("1","2","3","4","6","8"))]]
#    mpg cyl  disp  hp drat    wt  qsec vs am gear  carb
#1: 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4 Type2
#2: 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4 Type2
#3: 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4 Type1
#4: 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3 Type1
#5: 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3 Type1
#6: 18.1   6 225.0 105 2.76 3.460 20.22  1  0    3 Type1
#7: 14.3   8 360.0 245 3.21 3.570 15.84  0  0    3 Type2
#8: 24.4   4 146.7  62 3.69 3.190 20.00  1  0    4 Type1
#9: 22.8   4 140.8  95 3.92 3.150 22.90  1  0    4 Type1
#10: 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4 Type2
#...
...