Luker354
Luker354

Reputation: 669

Split named numeric vector into different elements in R

I have a named numeric vector in R with more than 2000 named numbers. I would like to split each element, in which the number is higher than 1, into the number of elements as indicated by the number, to have in the end only the number 1. But the important thing is to have also the names changed as indicated in my output.

Input:

obj<- c(3,1,1,1,6,1,1,1,1,1,1,1,1,3)
names(obj)<- c("V4","V10","V12","V15","V16","V20","V21","V22","V23","V36","V39","V40","V41","V42")

>obj
   V4   V10   V12   V15   V16   V20   V21   V22   V23   V36   V39   V40   V41   V42 
    3     1     1     1     6     1     1     1     1     1     1     1     1     3

Output:

obj_out<- c(1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3)
    names(obj_out)<- c("V4_1","V4_2","V4_3","V10","V12","V15","V16_1","V16_2","V16_3","V16_4","V16_5","V16_6","V20","V21","V22","V23","V36","V39","V40","V41","V42_1","V42_2","V42_3")

 > obj_out
 V4_1  V4_2  V4_3   V10   V12   V15 V16_1 V16_2 V16_3 V16_4 V16_5 V16_6   V20   V21 
    1     1     1     1     1     1     1     1     1     1     1     1     1     1 
  V22   V23   V36   V39   V40   V41 V42_1 V42_2 V42_3 
    1     1     1     1     1     1     1     1     1 

I have already a code, but it names the sequence completely new, starting with V1:

obj_out<- paste0("V",rep(seq_along(obj_out), obj_out), "_", sequence(obj_out))

Upvotes: 2

Views: 202

Answers (2)

tmfmnk
tmfmnk

Reputation: 39858

One option utilizing purrr could be:

imap(obj[obj > 1], ~ set_names(rep(1, .x), paste(.y, 1:.x, sep = "_"))) %>%
 reduce(c) %>%
 c(., obj[obj == 1])

 V4_1  V4_2  V4_3 V16_1 V16_2 V16_3 V16_4 V16_5 V16_6 V42_1 V42_2 V42_3   V10   V12 
    1     1     1     1     1     1     1     1     1     1     1     1     1     1 
  V15   V20   V21   V22   V23   V36   V39   V40   V41 
    1     1     1     1     1     1     1     1     1 

Upvotes: 1

Ronak Shah
Ronak Shah

Reputation: 388982

Here is one base R approach :

#Repeat each value in obj, obj number of times
res <- rep(obj, obj)
#Change all values to 1.
res[] <- 1
#Change the names
names(res) <- ave(names(res), names(res), FUN = function(x) 
                  if(length(x) == 1) x else paste(x, seq_along(x), sep = '_'))
res

# V4_1  V4_2  V4_3   V10   V12   V15 V16_1 V16_2 V16_3 V16_4 V16_5 V16_6 
#    1     1     1     1     1     1     1     1     1     1     1     1 
#  V20   V21   V22   V23   V36   V39   V40   V41 V42_1 V42_2 V42_3 
#    1     1     1     1     1     1     1     1     1     1     1 

Upvotes: 2

Related Questions