3

I have the following database

library(data.table)
dt <- data.table(prod= c("AAAA","BBBB","CCCC"),
                 version= c(4,3,5))

And I want to obtain this

AAAA1
AAAA2
AAAA3
AAAA4
BBBB1
BBBB2
BBBB3
CCCC1
CCCC2
CCCC3
CCCC4
CCCC5

Now I have the following code, but it only works for the AAAA but not for the rest

list <- c()

for(i in 1:dt$version){
  
  list[[i]] <- paste0(dt$prod,i)
  
}

4 Answers 4

3

A base R option using rep + sequence + paste0

> with(dt,paste0(rep(prod,version),sequence(version)))
 [1] "AAAA1" "AAAA2" "AAAA3" "AAAA4" "BBBB1" "BBBB2" "BBBB3" "CCCC1" "CCCC2"
[10] "CCCC3" "CCCC4" "CCCC5"

or mapply + paste0 + seq

> with(dt, unlist(mapply(function(x,y) paste0(x,seq(y)), prod,version)))
  AAAA1   AAAA2   AAAA3   AAAA4   BBBB1   BBBB2   BBBB3   CCCC1   CCCC2   CCCC3
"AAAA1" "AAAA2" "AAAA3" "AAAA4" "BBBB1" "BBBB2" "BBBB3" "CCCC1" "CCCC2" "CCCC3"
  CCCC4   CCCC5
"CCCC4" "CCCC5" 
Sign up to request clarification or add additional context in comments.

Comments

2

Using uncount

library(dplyr)
library(tidyr)
library(stringr)
dt %>%
   uncount(version) %>%
   mutate(prod = str_c(prod, rowid(prod)))

-output

#    prod
# 1: AAAA1
# 2: AAAA2
# 3: AAAA3
# 4: AAAA4
# 5: BBBB1
# 6: BBBB2
# 7: BBBB3
# 8: CCCC1
# 9: CCCC2
#10: CCCC3
#11: CCCC4
#12: CCCC5

Or with rep

dt[rep(seq_len(.N), version)][, prod := paste0(prod, rowid(prod))][]

Comments

2

Another way to do it is by using the Map and sprintf functions (from base) as follows

library(data.table)

dt <- data.table(prod = c("AAAA","BBBB","CCCC"),
                 version = c(4,3,5))

dt[, .(result = unlist(
         Map(f = function(x, y) sprintf("%s%d", x, seq(from = 1, to = y)),
             prod, version)
       ))]
#     result
#  1:  AAAA1
#  2:  AAAA2
#  3:  AAAA3
#  4:  AAAA4
#  5:  BBBB1
#  6:  BBBB2
#  7:  BBBB3
#  8:  CCCC1
#  9:  CCCC2
# 10:  CCCC3
# 11:  CCCC4
# 12:  CCCC5

Alternatively

with(dt, c(
         Map(f = function(x, y) sprintf("%s%d", x, seq(from = 1, to = y)),
             prod, version),
         recursive = TRUE, use.names = FALSE
       ))
#  [1] "AAAA1" "AAAA2" "AAAA3" "AAAA4" "BBBB1" "BBBB2" "BBBB3" "CCCC1" "CCCC2"
# [10] "CCCC3" "CCCC4" "CCCC5"

Comments

0

A dplyr option :

library(dplyr)

dt %>%
  slice(rep(row_number(), version)) %>%
  group_by(prod) %>%
  mutate(prod = paste0(prod, row_number())) %>%
  select(-version)

#   prod 
#   <chr>
# 1 AAAA1
# 2 AAAA2
# 3 AAAA3
# 4 AAAA4
# 5 BBBB1
# 6 BBBB2
# 7 BBBB3
# 8 CCCC1
# 9 CCCC2
#10 CCCC3
#11 CCCC4
#12 CCCC5

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.