R - Dataframe - Replace characters in a string using two columns containing lists of positions and characters

Viewed 49

First time poster, so please let me know how to improve my question if needed. Certainly eager to improve.

I have a data frame that has a column of strings that I need to replace characters in using a column containing a list of multiple positions and another column with a list of characters for those positions. Using example data:

#create the values to build the data frame for use case
food <-"pasta"
string <-"bacorogi"
pos <- c(1,4,7)
chars <- c("m","a","n")

#convert vectors to lists
poslist <-list(pos)
charlist <-list(chars)

#create data frame
df <-data.frame(cbind(food,
           poslist,
           charlist,
           string))

I figured out how to do this when the string, positions, and characters exist as separate vectors using:

for(i in seq_along(pos)) substring(string, pos[i], pos[i]) <- chars[i]
string
[1] "macaroni"

When I try to apply this to the data frame I run into an error:

for(i in seq_along(df$pos)) substring(df$string, df$pos[i], df$pos[i]) <- df$chars[i]

Error in `substring<-`(`*tmp*`, df$pos[i], df$pos[i], value = df$chars[i]) : 
  (list) object cannot be coerced to type 'integer'

To try to properly apply this to a data frame, I tried below and got an error:

 for(i in seq_len(nrow(df))) substring(df$string, df$poslist[i], df$poslist[i]) <- df$charlist[i]

Error in `substring<-`(`*tmp*`, df$poslist[i], df$poslist[i], value = df$charlist[i]) : 
  (list) object cannot be coerced to type 'integer'

I am not really sure how to get around this problem or how to adapt this to a data frame.

I do have more rows in my data frame, but I figured if someone could help me figure out how to do this to one row, I could take it from there. Thanks for any input you can provide!

1 Answers

The nesting is one level deep. So, extract that element and loop

for(i in seq_along(df$pos[[1]])) {
  substring(df$string[[1]], df$pos[[1]][i], 
        df$pos[[1]][i]) <- df$charlist[[1]][i]
 }

-output

df$string
#$string
#[1] "macaroni"

If there are more rows, do a nested loop

for(i in seq_along(df$pos)) {
   for(j in seq_along(df$pos[[i]])) {
      substring(df$string[[i]], df$pos[[i]][j], 
        df$pos[[i]][j]) <- df$charlist[[i]][j]
   }
 }


df$string
#$string
#[1] "macaroni"
Related