-5

I would like to know how to use stings stored in a variable/vector/matrix etc

in the middle of coding in order to edit names of variables/vectors or functions

e.g.

instead of creating the below

v_name1<- rep(5,10)
v_name2<- rep(30,10)
.
.
. 


function_name1<- { ... }
function_name2<-{ ... } 

.
.
. 

using a for loop instead

I already know e.g. (this is just an example to illustrate)

  s<-c("name1","name2", ... )

for (i in 1:(length(s))) {
    eval(parse(text=paste("v_",s[1],"<-c(rep(i,10))", sep="")))
    }
        v_name1
         [1] 1 1 1 1 1 1 1 1 1 1

I have two problems :

1) How do you make this for functions, I get the below error? e.g.

st<- "(x,y)<-{ 3*x + y}"
eval(parse(text=paste("function_",s[1],st, sep="")))

> eval(parse(text=paste("function_",s[1],st, sep="")))
Error in eval(expr, envir, enclos) : object 'x' not found

2) is there any faster/smarter way to do just that (substitute part of the coding with strings saved into another object) ?

I do not want to share what is my end goal or why I need to do this, I just want to know if the 2 things above are plausible.

Roland
  • 127,288
  • 10
  • 191
  • 288
Dionysios
  • 49
  • 2
  • 9
  • 1
    Use lists - `dataList <- split(data, data$country)`, why function names have to be "country" specific? – zx8754 Jun 29 '16 at 10:45
  • because in reality they are many countries (not just 3) and although I could name them like e.g. fun_country1, fun_country2 etc .. that means that whenever I or someone else would have to use the code they would need to refer to a reference table to see which country_number is which country etc when in a practical manner most of the people know the country codes. In a more general manner, the idea here for me is to see how I could use wherever in my coding strings saved in other variables. – Dionysios Jun 29 '16 at 10:52
  • 1
    I think you are over-complicating it. Say you have `data` object with `Country` column, at the beginning set a variable `countyCode <- "UK"`, then work with subsetted data `dataSubset <- data[ data$Country == countryCode, ]`, and the rest of your codes and functions should stay the same, working on `dataSubset` object only. – zx8754 Jun 29 '16 at 11:02
  • thank you very much for the answer and your time, I have already thought of what you are suggesting ... my point is bigger here, not just for this specific case. I wan to know in general how I could use stings saved somewhere (variable, vector etc) in coding on the fly, dynamically . Imagine of about 15 countries (which might change in the future) and giving my code to someone else and asking them to use a lot of functions and data and for each country to remember the naming (countrycode1, countrycode2 etc ... ) i.e. every person using the code would need to learn my personal country reference – Dionysios Jun 29 '16 at 11:12
  • Then you are stepping into the [eval(parse()) world](http://stackoverflow.com/questions/11025031). – zx8754 Jun 29 '16 at 11:19
  • thank you! I was trying to avoid that due to the coding-time required , but I guess (from what ever research I have done until now) that must be the main option and for this project I require to apply it. – Dionysios Jun 29 '16 at 11:24
  • 1
    Oh don't, I still don't understand why working on subsetted data option wouldn't work. And you didn't clarify why would you need function names having country names attached to it. – zx8754 Jun 29 '16 at 11:29
  • the subset was just to show how my data are,(I am thinking to remove it, as it is misleading). The important thing is the function names and some vectors. The reason is because imagine a team of people needing to use more than 20 functions and many vectors which each refers to a specific country. They need to be** meaningful**. The countries will change in the future (they might not even be country names) . It is not efficient to ask many people to learn by heart 15 or more country code references. They could be products , imagine asking 20+ people learning which code refers to which product. – Dionysios Jun 29 '16 at 11:48
  • Still not clear, are you saying `myFunction_UK()` will be doing different things compared to `myFunction_US()`? I suggest you edit your post. – zx8754 Jun 29 '16 at 11:54
  • Edited the question .. I do not know whether maybe I should just delete and re-post – Dionysios Jun 29 '16 at 13:54
  • The "easier/smarter/faster" way is to *not* do this at all. Using lists or another approach without dynamically defining function names and content via strings is all three: easier, smarter and faster. – Gregor Thomas Jun 29 '16 at 22:55
  • Your newest attempt only fails because you paste together `function(x,y)<-{ 3*x + y }`, which isn't valid syntax. If you turned it into something like `"bad_idea <- function(x,y) {3*x + y}"` you could eval/parse it and it would work, though it would still be a bad idea. – Gregor Thomas Jun 29 '16 at 22:59
  • you are right and I was blind ... about the wrong syntax, Thank You Very Much! It was that simple :) . Now about the rest well I understand that people love being judgmental. There are points that we(all of us) just need to know if something (specific) is possible or not, and find the most efficient way to do just that. I do not see why I would need to share the whys or all of my project, aren't the " for general R knowledge" or " just in case for the future" just enough ? I do agree though that my original question was misleading. Again thanks. – Dionysios Jun 29 '16 at 23:18

1 Answers1

2

The very first comment told you to use lists. You can put anything into a list, data as well as functions:

set.seed(42)
v <- list(uk = rnorm(10, mean = 5), us = rnorm(10, mean = 30), fr = rnorm(10, mean = 300))
funs <- list(uk = mean, us = median, fr = min)

You can then do this:

country <- "us"
funs[[country]](v[[country]])

R is not a language with macros. Work with the language and not against its design. And forget eval(parse()).

Roland
  • 127,288
  • 10
  • 191
  • 288
  • 2
    You have not adequately described your problem if this dorsn't solve it. In fact, you are probably approaching the whole task in a wrong way. – Roland Jun 29 '16 at 16:35
  • I see your and zx8754's point for the list usage and it is a nice implementation . Yet still my problem is that e.g. in a months time I might get a new data frame with 15 other countries (or not even countries), so imagine having to go back to several lines of code in order to change each name. I do have an alternative way to implement what I need but running time will get 11 times slower. I want the code to work just by giving a different vector with the new names (countries,or whatever) so that the people using it (not programmers), know that function1_"new_name" does what supposed to. – Dionysios Jun 29 '16 at 16:36
  • I do not want you to resolve my project ... I just want to know how and if I am able to replace coding with strings saved in another variable, specially in the case of functions (and this is a general question, not just for what I am implementing right now) – Dionysios Jun 29 '16 at 16:42
  • 2
    It's quite simple. You are asking for something you do not need. I'm sure there is an easy way to solve your actual problem, which however you have not described sufficiently. – Roland Jun 29 '16 at 18:23
  • you are right , I edited my question. I just wanted to know that specifically and I made that e.g. up (in my project I will use that in a different manner) – Dionysios Jun 29 '16 at 23:25
  • 1
    That doesn't change the answer. Just use lists. – Roland Jun 30 '16 at 06:59
  • hahah ... so if someone asked I want instead of doing a<-rep(5,3) to know if there is a way to do it manually (i.e. he is looking for the option a<-c(5,5,5) , regardless for the whys, you would still insist on telling them "just use rep ?" ). In any case I can do what I need in about 10 lines of code, instead of 100 (without even using lists, just from the original data.frame). However there are reasons that I needed to know if there was that option. I just do not want to share the whys. In any case thank you for your time and effort. I do realize that you just want to help me get better. – Dionysios Jun 30 '16 at 08:32
  • Sorry for the spam,I can't move to chat yet.The coding must be flexible/adaptable to different scenarios.In your answer, let's say that in a month time you get 15 products instead of 3 countries(car, tea,etc).How would you edit the 2 lists without having to manually change the names and add the 12 new list names and function names ?.These functions although different, they do have an algorithm that creates them, however for speed reasons they need to be ready to use, not created on the fly(i.e a single function with name as an input is not an option),lastly name should associate with the data. – Dionysios Jun 30 '16 at 09:06
  • 2
    What you don't seem to grasp: Your suggested approach is considered extremely bad practice. And for good reasons, among them that it is difficult to maintain and debug. There are better approaches, which are also quite easy. However, it's hard to show you without a representative example. Your problem seems to be that you are stuck at your bad approach and unable to consider better approaches. – Roland Jun 30 '16 at 09:32
  • @ Roland Thank you very much Ronald for insisting. I am sorry for my stubbornness ... eventually I did implement (and still am) the way you indicated. – Dionysios Jun 30 '16 at 23:07