在字符串 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)
)
我想将一个数字和一些字母粘贴在一起以便为它们编制索引。我的数据框的列如下;
当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)
)