0

I have ten age columns in my data frame named similarly (i.e. agehhm1, agehhm2, …, agehhm10) that should hold age in years for a person. Currently, they are all strings as some observations include the words "month", "mos", etc. as some people are less than 1 year old. I am trying to use lapply to loop through these columns and replace observations that include these string patterns with a "0" value. I am close but am getting stuck on how to name the new columns I want to assign the lapply output to. I am trying setNames. I am not getting an error, but nothing is changing in my dataframe.

I am trying the following. I store the 10 age columns in an object "hhages_varnames". Then I apply lapply to this list of objects, and replace the applicable obs in each one with 0 if I find any of the "month" text patterns. I am trying to create new columns named agehhm1_clean, etc as output.

I am open to any other methods that you think are better for any part of this.

hhages_varnames is just an object where I store the names of the 10 age columns. So it is just a 1:10 vector with "agehhm1" "agehhm2",..."agehhm10".

hhages_varnames <- ls(dataframe_name, pattern = "agehhm.*")
setNames(lapply(hhages_varnames, FUN = function(x) (replace(x, grepl("month|MO|mos|days|months", dataframe_name[,x]),"0"))), 
         paste(names(hhages_varnames),"clean", sep="_")) 
kayla
  • 1
  • 2
  • 1
    Your `setNames` adds a space into the names, I suggest `paste0` or `paste(..., sep='_')` or similar. Also, `setNames` does not operate in side-effect, you'll need to capture the return from `setNames` into some variable. – r2evans Mar 24 '20 at 21:22
  • It would be easier to help if you provide a sample of `hhages_varnames`. Perhaps with the `dput` function. – Ian Campbell Mar 24 '20 at 22:30
  • @r2evans and Ian Campbell thank you for your edit and comments. r2evans You are correct I was adding spaces in the paste on accident- good catch. I see what you are seeing now about setNames not operating in side-effect. Although, I am uncertain how to capture them into a variable seeing as I am trying to create 10 variables (i.e. one new one for each of the 10 original). Ian Campbell I have tried adding clarification in the post that hhages_varnames is just an object holding the var names of the 10 age variables. I can also try to add a file/photo of the variables themselves though. – kayla Mar 25 '20 at 03:34
  • kayla, if the frames are at all similar, it is strongly recommended to keep it as a single `list` of `data.frame`s: when you do something to one of them, do the same thing to all of the frames effortlessly using `lapply`. Ref: https://stackoverflow.com/a/24376207 ... it's worth it in the long run, where you don't get if the list has 3 frames or 300, your effort is the same. – r2evans Mar 25 '20 at 03:36
  • 1
    @r2evans my apologies-I think I am mis-using the word variable here- I think I should be saying columns in my dataframe. I only have one dataframe with 10 columns that I am working with. – kayla Mar 25 '20 at 03:41
  • Ahh. `as.data.frame(lapply(...))` will turn a list of same-length vectors into a frame, `setNames` works on that as well, so you can do `setNames(as.data.frame(lapply(...)), paste(...))` or `as.data.frame(setNames(lapply(...), paste(...)))`. Note that you may need `stringsAsFactors=FALSE` if you want strings and not `factor`s. – r2evans Mar 25 '20 at 04:06
  • @r2evans thank you for bearing with me! I was able to get it to work! I will put final code in question. – kayla Mar 25 '20 at 16:03

1 Answers1

0

UPDATE: Here is the final code that I got to do what I was wanted. It worked to use as.data.frame to make the vectors into a data frame. I also ended up using cbind to add the new columns to my existing dataframe. Thank you!

hhages_varnames <- ls(dataframe_name, pattern = "agehhm.*")
dataframe_name <- cbind(dataframe_name, setNames(as.data.frame(lapply(hhages_varnames, FUN = function(x) (replace(dataframe_name[,x], grepl("month|MO|mo|days|months", dataframe_name[,x]),"0")))), 
       paste0(as.list(hhages_varnames),"clean")))
kayla
  • 1
  • 2