for loop with dimension of a list [closed] - r

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I have a code,and i am going to do a for loop on two gamma distributions.
Given the list of shape parameter, and i name them "d" then i put in d[1] and d[2] in the random gamma function.
I have simplified what I wish to ask here. when i code d[1] in R, output will be the first vector,while when i code d[2] in R, output will be the second vector.
I have a bit lose then how will it iterate if i using for loop for d ?
*
List_1 <- list(c(4,16),c(16/9,4),c(1,16/9),c(.64,1),c(4/9,.64))
for ( d in List_1) ##first parameter is for gamma.1, second is for gamma.2
{
x<-rgamma(25,d[1],1)
y<-rgamma(25,d[2],1)
t<-t.test(x,y)$p.value
}*
I am sorry if i do ask a silly question. Thanks in advance.

In R it is better to avoid for loops due to their poor performance. Since you are starting with a list lapply is a good start:
lapply(List_1, FUN=function(x){t.test(rgamma(25,x[1],1), rgamma(25,x[2],1))$p.value})
The apply function takes your list and then uses the gamma function on the 2 parameters within the t.test. The result will be a list of the five p values, one for each pair

Your code runs fine. I am actually not sure what you are asking here. You can just use print to find the iteratives, if that is what you want, like:
for (d in List_1){
print(d[1])
print(d[2])
}

Related

good practice to use "$" and run a function in one line in R [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Today i have seem a "strange" thing and am wondering if this is a good practice. Basically there is a list:
testList <- list("columnA" = c(1, 2, 3),
"columnB" = c(11,22,33))
and then a function:
calculateMean <- function(input){
out <- lapply(input, mean)
return(out)
}
and the this:
resultTest <- calculateMean(testList)$columnA
Question: Is this a good practice to refer to functions result without storing the results of a function in an intermediate step?
We may use sapply and return a named vector and store it as a single vector and use that for other cases i.e. suppose we want to take the max of that vector, it can be applied directly instead of unlist the list.
calculateMean <- function(input){
out <- sapply(input, mean)
return(out)
}
-ouptut
calculateMean(testList)
columnA columnB
2 22
Regarding storing the output, it depends i.e. if we want to extract the output of 'columnB', we may need to run it again and do $. Instead, save it as a single object and extract as needed
You ask if this is good practice. I'd say there are good and bad aspects to it.
On the positive side, it keeps your code simpler than if you defined a new variable to hold calculateMean(testList) when all you are interested in is one element of it. In some cases (probably not yours though) that could save a lot of memory: that variable might hold a lot of stuff that is of no interest, and it takes up space.
On the negative side, it makes your code harder to debug. Keeping expressions simple makes it easier to see when and why things aren't working. Each line of
temp <- calculateMean(testList)
resultTest <- temp$columnA
is simpler than the one line
resultTest <- calculateMean(testList)$columnA
In some situations you could use an informative name in the two-line version to partially document what you had in mind here (not temp!), making your code easier to understand.
If you were trying to single step through the calculation in a debugger, it would be more confusing, because you'd jump from the calculateMean source to the source for $ (or more likely, to the final result, since that's a primitive function).
Since the one-line version is relatively simple in your case, I'd probably use it, but in other situations I might split it into two lines.

How could I make a function thar goes trough a vector and recognizes the signs of the numbers on it? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I was wondering if someone can help me with this, I need a function that goes trough a vector and recognizes the signs of the numbers inside, thats de basic idea, then I'll try to make some modifications so the function counts every number and shows something like "There are 2 positive numbers and 3 negatives"
What about the following approach (I added also functionality for zeros, remove this feature if it is not needed, or merge it with one of the other two conditions):
sign_function <- function(x){
count_pos_numbers = sum(x>0)
count_neg_numbers = sum(x<0)
count_zeros = sum(x==0)
sprintf("There are %d positive numbers, %d negative numbers, and %d zeros.", count_pos_numbers, count_neg_numbers , count_zeros)
}
I hope that I understood your question correctly.

Efficiently packing and unpacking function arguments in R [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I have some R code where I'm starting to get too many arguments in my functions, like this
f<-function(a,b,c,d,e,f,g,...){
#do stuff with a,b,c,d,e,f,g
return(list(q=q,r=r,s=s,...))
}
I was thinking of collapsing arguments into lists of related parameters and then extracting out the parameters from the lists inside the function. This is annoying though since I have to use a lot of boilerplate code
list_of_params<-list(a=a,b=b,...)
f<-function(list_of_params){
a<-list_of_params[["a"]]
b<-list_of_params[["b"]]
c<-list_of_params[["c"]]
...
#do stuff with a,b,c,...
return(list(q=q,r=r,s=s,...))
}
I was thinking about using something like list2env to automatically extract the variables from the list into the environment of the function. Does anyone have opinions about whether that is a reasonable approach? I read somewhere that using assign is a bad idea and this seems similar. My proposed function would look like this:
f<-function(list_of_params){
list2env(list_of_params, envir=as.environment(-1)) #-1 means current environment
#do stuff with a,b,c...
return(list(q=q,r=r,s=s,...))
}
I have never used assign() or list2env() before. I am concerned they may have treacherous pitfalls I should watch out for, in the same manner as attach(). Is the use of list2env() here appropriate? If not, what is the appropriate use of this function?
A long list of parameters is probably a code-smell.
The easiest thing to do is to stop, and think about what type of object that should encapsulate your parameters. It's probably not just a simple list.
Another option is if many of the function parameters are held fixed in terms of procedural or lexical scope. Then you could use the fact that functions are R are closures. Example:
make_f <- function(object, params){
e <- calculate_e(object, params)
f <- calculate_f(object, params)
g <- calculate_g(object, params)
f<-function(a,b,c,d,...){
#do stuff with a,b,c,d,e,f,g
return(list(q=q,r=r,s=s,...))
}
return(f)
}

Remove first row conditionally [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
This is a very simple problem and I'll probably catch flame for asking this, but I've looked everywhere and I can't find the answer... Or a different approach to my code.
I need to remove the first row of a data frame if the value of the first row and third column are equal to one.
This is what I have so far:
if (foo[1, 3] == 1) {
foo <- foo[-1, ]
}
Is there a different way to do this using only bracket subsetting (avoiding using an if statement)?
Edit:
Edited for clarity.
The code you wrote doesn't remove the first row permanently, it only prints it out. Change that with foo<-foo[-1, ]
Additionally, the code within the if-statement brackets is only one line anyway, you don't technically need them, but some like them for clarity purposes
if (foo[1, 3] == 1) foo <- foo[-1, ]

how to paste string in R [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I want to paste 4 strings together, the code is here:
urlstring<-"lee/"
code<-read.csv("D:\\list.csv",sep="\n",head=FALSE)
for(y in code){count<-1
while(count<3){
mydate<-Sys.Date()-count
filename<-paste(urlstring,mydate,"&symbol=",y,sep="")
print(filename)
count<-count+1
}
}
my question is why the output is, date is changing firstly :
lee/date=2013-11-14&symbol=1
lee/date=2013-11-14&symbol=2
lee/date=2013-11-13&symbol=1
lee/date=2013-11-13&symbol=2
but in my opinion,the result should be this,the value of code should be changed firstly:
lee/date=2013-11-14&symbol=1
lee/date=2013-11-13&symbol=1
lee/date=2013-11-14&symbol=2
lee/date=2013-11-13&symbol=2
Like #mnel said. for code = 1:2 your code yields the correct results. Note that the nested for-while loop is not needed, a vectorized solution uses less code is and is often faster:
code = rep(1:2, each = 2)
mydate = Sys.Date() - code
sprintf('lee/date=%s&symbol=%d', mydate, code)
[1] "lee/date=2013-11-14&symbol=1" "lee/date=2013-11-14&symbol=1"
[3] "lee/date=2013-11-13&symbol=2" "lee/date=2013-11-13&symbol=2"
This solution is called vectorized because when sprintf is used with vectors, the result is also a vector, without explicitily using a loop.

Resources