4

A have a list that has the following structure.

mylist=list(y~ A,
y ~ A+B,
y ~ A+B+C)

I want to replace (recode) the “y “ with a “z”. my goal is

mylist=list(z~ A,
z ~ A+B,
z ~ A+B+C)

Q: How to replace (recode) values in a list?

I have tried this:

for i in range(len(mylist)):
  mylist[i] = mylist[i].replace('y','z')

is not working

5
  • 3
    This doesn't look like r code. Did you mean to tag with python perhaps? Commented Jul 25, 2016 at 13:00
  • @docendo discimus, ....Ah, that makes the sense. I got the example from a website in which is was sold as an R code. That explains the mix up part of my trial. I was looking for an R solutions Commented Jul 25, 2016 at 13:08
  • So try to check answer i published. It's great text from AdvancedR to understand elements in list “If list x is a train carrying objects, then x[[5]] is the object in car 5; x[4:6] is a train of cars 4-6.” Commented Jul 25, 2016 at 13:10
  • 1
    Try lapply(mylist, function(x) reformulate(as.character(terms(x))[3], "z")) maybe in R Commented Jul 25, 2016 at 13:14
  • Thanks, @DavidArenburg. It works. But way is R putting e.g., "<environment: 0x16313cd4>" in the list. Where does that come from/way is R doing that? I hope you or someone else can explain way. Commented Jul 25, 2016 at 13:23

4 Answers 4

13

The update function is useful for formulas.

Just include a . to indicate any formula side to retain. So, for your problem the following is a quick one-liner.

lapply(mylist, update, new = z~.)

Sign up to request clarification or add additional context in comments.

1 Comment

This seems like the best option. I didn't know update has an update.formula method
6

I would alternatively suggest to use R built in formulas manipulation functionality. This allows us to operate on different terms of a fromula separately without using regex

lapply(mylist, function(x) reformulate(as.character(terms(x))[3], "z"))
# [[1]]
# z ~ A
# <environment: 0x59c6040>
#   
# [[2]]
# z ~ A + B
# <environment: 0x59c0308>
#   
# [[3]]
# z ~ A + B + C
# <environment: 0x59bb7b8>

Comments

2

Since you have a list of formulas as a start, you can convert the formulas to characters, use gsub to do the replacement and convert it back to formula. Use env parameter to specify the environment of the formulas to make sure they are the same as original list:

lapply(mylist, function(f) formula(gsub("y", "z", format(f)), env = .GlobalEnv))
# [[1]]
# z ~ A

# [[2]]
# z ~ A + B

# [[3]]
# z ~ A + B + C

To take care of the concern of @David Arenburg, so that the replacement of y will always happen on the left side of the formula, we can use a more restricted regular expression:

lapply(mylist, function(f) formula(gsub("y(\\s)?(?=~)", "z", format(f), perl = T), env = .GlobalEnv))

# [[1]]
# z ~ A

# [[2]]
# z ~ A + B

# [[3]]
# z ~ A + B + C

4 Comments

@ Psidom, this makes me smile, again. Thanks. I have one little question, way “env = .GlobalEnv” ? it helps me to understand. Thanks
I don't think this safe enough. What would happen for a formula such as y ~ city + country? Or how will you handle different names in the response variable? This regex isn't targeting just the response variable.
@DavidArenburg I am assuming the case is very restricted to OP's description. But I consider the concern is valid here, just updated the answer to make it more general.
env = .GlobalEnv assign the environment of an object. Since the formula is generated in a function, by default, it will have an environment local to the function which is not the case in your original list. Assign the global environment to these formulas will make sure they are visible in the global R session.
2

Just like expressions, formulas have replaceable parts. So you could use [[<- to replace parts of the formula. The y value is the second in the expression list, as ~ is a function and hence the first.

lapply(mylist, "[[<-", 2, as.name("z"))
# [[1]]
# z ~ A
#
# [[2]]
# z ~ A + B
#
# [[3]]
# z ~ A + B + C

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.