Search code examples
rif-statementreplacesapply

Replace elements in a list of lists with elements found on different dataframe based on if condition with R


I have a list of lists which contains states of the US as full names.

l1<-list(list(c("Arizona")),list(c("California")),list(c("Texas","California","Alabama")))

What I want to do is replace full names with state acronyms which I have in a different dataset.

data("state.fips" )
state.fips<-data.frame(state.fips)

In order to convert the first letter of every state as capital in state.fips and create the new column COL2 I used:

firstup <- function(x) {
      substr(x, 1, 1) <- toupper(substr(x, 1, 1))
      x
    }

state.fips$polyname<- firstup(state.fips$polyname)

state.fips$COL2 <- gsub("([A-Za-z]+).*", "\\1", state.fips$polyname)

Then i create a new empty list:

l2 <- vector('list', 3)

And i try to replace the full names of the states with the states acronyms based on the state.fips dataset:

for(i in 1:3){
   l2[[i]]<-lapply(l1[[i]], function(x)x[which(x %in% state.fips[j,7] )])
   for(j in 1:63){
     if(sapply(l2[[i]], function(x) length(x) > 0)==TRUE){
       l2[[i]]<-gsub(l1[[i]],state.fips[j,5],l1[[i]])
     }
     else{
       l2[[i]]<-l1[[i]]
     }
   }}

Obviously it is not working and more specifically in lists with more than one names it does not even perform the replacement. Any suggestions?


Solution

  • First thing is, you do not only have a list in a list, but in there is another vector. That is maybe why you only replaced the first 'element'.

    I suggest, using 2 lapply and a sapply.

    l2 <- lapply(l1, function(sublist){ # iterates over the first list
      lapply(sublist, function(state.vector){ # iterates over the second list inside the first list
        sapply(state.vector, function(state){ # iterates over the vectors inside the second list
          return(state.fips[which(state.fips[,'COL2'] == state),'abb']) # select the abbreviation based on the statename in COL2
        })
      })
    })