1
votes

I have a for loop,where I create a data frame inside that.Because of that data frame will take different shape in each round.Sametime I create string vector in each round where length of the vector is equal to number of columns of the data frame. as a example in a random round,data frame is merged_ and string vector is out.names

merged_ <-  data.frame(V8 = c(19, 19, 1, 4, 4, 4),
                 V9 = c("9P0480", "9P0480", "9P0480", "9P0480", "9P0480", "9P0480"),
                 V10 = c(0,0,0,0,0,0),
                 V11 = c(4580,4580,4580,4580,4580,4580))

out.names <- c("hello","hello2","hello3","hello4")

Now I need to update each column by add string value as a prefix. output like this

df_new <- data.frame(V8 = c("hello:19", "hello:19", "hello:1", "hello:4", "hello:4", "hello:4"),
V9 = c("hello2:9P0480", "hello2:9P0480", "hello2:9P0480", "hello2:9P0480", "hello2:9P0480", "hello2:9P0480"),
V10 = c("hello3:0","hello3:0","hello3:0","hello3:0","hello3:0","hello3:0"),
V11 = c("hello4:4580","hello4:4580","hello4:4580","hello4:4580","hello4:4580","hello4:4580"))

        V8            V9      V10         V11
1 hello:19 hello2:9P0480 hello3:0 hello4:4580
2 hello:19 hello2:9P0480 hello3:0 hello4:4580
3  hello:1 hello2:9P0480 hello3:0 hello4:4580
4  hello:4 hello2:9P0480 hello3:0 hello4:4580
5  hello:4 hello2:9P0480 hello3:0 hello4:4580
6  hello:4 hello2:9P0480 hello3:0 hello4:4580

what I tried so far is,trying to update each column using for loop.

for (col in 1:ncol(merged_)) {

    merged_[,col] <- paste0(out.names[col],":",merged_[,col])
  }

This is the error when I try above code

Error in [.data.table(merged_, , col) : j (the 2nd argument inside [...]) is a single symbol but column name 'col' is not found. Perhaps you intended DT[,..col] or DT[,col,with=FALSE]. This difference to data.frame is deliberate and explained in FAQ 1.1.

Is this can be solved by using some Vectorization method,without using for loop.

2

2 Answers

1
votes

We can use Map and paste values from out.names and merged_ column-wise.

merged_[] <- Map(paste, out.names, merged_, sep = ":")
merged_

#        V8            V9      V10         V11
#1 hello:19 hello2:9P0480 hello3:0 hello4:4580
#2 hello:19 hello2:9P0480 hello3:0 hello4:4580
#3  hello:1 hello2:9P0480 hello3:0 hello4:4580
#4  hello:4 hello2:9P0480 hello3:0 hello4:4580
#5  hello:4 hello2:9P0480 hello3:0 hello4:4580
#6  hello:4 hello2:9P0480 hello3:0 hello4:4580

This is similar to map2 in purrr.

merged_[] <- purrr::map2(out.names, merged_, paste, sep = ":")
0
votes

We can use map2_df from purrr with str_c

library(stringr)
library(purrr)
library(tidyr)
map2(out.names, merged_, ~ str_c(.x, .y, sep=":") %>% 
       as.list) %>% 
       tibble(new = .) %>%
  unnest_wider(new)