在字符串 R 上粘贴字母索引

Paste letter index on string R

我想将一个数字和一些字母粘贴在一起以便为它们编制索引。我的数据框的列如下;

当CNTR为NA时,我希望它是预订号+一个索引,所以以预订202653为例,我希望它是202653A和202653B。当 CNTR 列为空时,我已经实现了将预订号粘贴到 CNTR 列中;

dfUNIT$CNTR <- ifelse(is.na(dfUNIT$CNTR), dfUNIT$BOOKING, dfUNIT$CNTR)

这给了我以下 table;

但正如我所说,我需要唯一的 CNTR 值。我的数据框包含数千行并且经常更改,有没有办法按照我想要的方式 'index' 它们(A、B、C 等)?提前谢谢你

我补个资料,

dat <- data.frame(B=c(202658,202654,202653,202653),C=c("TCLU","KOCU",NA,NA))

dplyr

library(dplyr)
dat %>%
  group_by(B) %>%
  mutate(C = if_else(is.na(C), paste0(B, LETTERS[row_number()]), C))
# # A tibble: 4 x 2
# # Groups:   B [3]
#        B C      
#    <dbl> <chr>  
# 1 202658 TCLU   
# 2 202654 KOCU   
# 3 202653 202653A
# 4 202653 202653B

其中的一个基本风险是,如果您有超过 26 行的预订,在这种情况下,字母后缀将失败。另一种方法是附加一个数字(例如 paste0(B, "_", row_number()) 或添加一些其他保护措施。

基础 R 替代品

do.call(rbind, by(dat, dat[,"B",drop=FALSE],
                  FUN = function(z) transform(z,
                    C = ifelse(is.na(C), paste0(B, LETTERS[seq_along(z$C)]), C)
                  )
))

append <- ave(dat$C, dat$B, FUN = function(z) ifelse(is.na(z), LETTERS[seq_along(z)], ""))
append
# [1] ""  ""  "A" "B"
dat$C <- paste0(ifelse(is.na(dat$C), dat$B, dat$C), append)
dat
#        B       C
# 1 202658    TCLU
# 2 202654    KOCU
# 3 202653 202653A
# 4 202653 202653B

如果您不坚持使用字母来索引转换,这里有一个大致的 dplyr 解决方案,该解决方案基于 data.table 包中的 rleid

library(dplyr)
library(data.table)
df %>%
  group_by(grp = rleid(B)) %>%
  mutate(CNTR_new = if_else(is.na(CNTR), paste0(B, "_", grp), CNTR))
# A tibble: 7 x 4
# Groups:   grp [5]
      B CNTR    grp CNTR_new
  <dbl> <chr> <int> <chr>   
1    12 TCU       1 TCU     
2    13 NA        2 13_2    
3    13 NA        2 13_2    
4    15 NA        3 15_3    
5     1 PVDU      4 PVDU    
6     1 NA        4 1_4     
7     5 NA        5 5_5 

数据:

df <- data.frame(
  B = c(12,13,13,15,1,1,5),
  CNTR = c("TCU", NA, NA, NA, "PVDU", NA, NA)
)