If statement with multiple actions in R - r

I would like to write an if statement of the following form:
a=5
b=2
la<-function(a,b){
if(a>3){a}
else{b}
}
Now what I would like to do is not only have one action in the if statement but two, for example:
if(a>3){a and c<<-1000}
In this case to return 'a' and also write 1000 in variable 'c'
My question is how to put in multiple actions after the if statement.

You should use the semicolon
if(a>3){c<-1000;a}
The last statement is the return value.
EDIT This works for multiple statements, too. You can omit the semicolon if you use line breaks, as in
if(a>3) {
c<-1000
d<-1500
a
} else {
e <- 2000
b
}
EDIT: this should work with ifelse too. You would have to keep in mind that you are operating on a vector, though. Here is an example:
x <- sample(10, 100, replace=TRUE)
ifelse(x>3, {y <- 100; y+x}, x)
This adds 100 only to those elements of x that are larger than 3.

Related

How do you generate the output of for loop and if statement into a list or vector?

I have tried the following but the output brings an argument stating,
Error in append("0") : argument "values" is miss
for (rowz in final_data$Ingridients) {
Cobalt_row<-lst()
if (sum(str_detect(rowz, 'Cobalt'))>0) {
Cobalt_row.append(1)
} else {
Cobalt_row<-append(0)
}
print(Cobalt_row)
}
I intended to loop through the list and generate a boolean of ones and twos depending on
whether or not I had the value.
Please help
Without the data, I can't test it, but this should work:
Cobalt_row<-lst()
k <- 1
for (rowz in final_data$Ingridients) {
Cobalt_row[[k]] <- ifelse(str_detect(rowz, 'Cobalt'), 1, 0)
k <- k+1
}
or even simpler if you need a list:
Cobalt_row <- as.list(as.numeric(str_detect(final_data$Ingredients, "Cobalt")))

Hi. I am new to R and am really struggling with writing my function with for and while loop. Can someone tell me the for and while loop for the qs?

Write a function h1 which uses a for-loop and the explicit formulation
h(x, n) = 1 + x + x2 + ...xn = ∑xn
Code:
h2 <- function(x,n){
i <- 1
out=0
for (i in seq(from=0,to=n)) {
out = out + x^i
}
}
I have tried this but this doesnt seem to work? Is there an alternative way to find the for and while loop for this problem
A function returns the result of the last statement in its body which in this case is for but for always returns NULL. (The line after the for is regarded as part of the for so it is not regarded as the last line.)
res <- for(i in 1:3) i
res
## NULL
Make sure that out is the last statement run. That is add this
out
as the last line in the body just before the final }.
Note that this one-linear would also work:
sum(x^(0:n))

Compare function ( ==, all.equal) is not working properly when it comes to two digit numbers in R?

I am trying to compare two number in my code, when it comes to compare one digit number , it works fine whether I use == or all.equall function, but when it comes to comparing 2 digit number or more like 17, it can't say they are the same, I have already go through this thread and all.equall is not working as well. beside my numbers are all integers. can any one tell me what the problem is here ?
I'll put the code here so the problem can be reproducible.
library(igraph)
node1<- c(1,1,1,2,2,2,3,3,4,4,5,5,7,8,9,9,10,12,14,14,17,17,19)
node2<-c(2,3,4,5,6,17,12,14,7,8,6,13,14,9,10,11,11,13,16,15,18,19,20)
AZADEH_GRAPH.data <- data.frame(node1,node2)
dataframe_AZADEH_GRAPH<-AZADEH_GRAPH
graph_AZADEH_GRAPH=graph.data.frame(dataframe_AZADEH_GRAPH,directed=FALSE)
Nodes1_AZADEH_GRAPH<- replicate(vcount(graph_AZADEH_GRAPH), 0)
SuperEgo_AZADEH_GRAPH<- list()
Com_AZADEH_GRAPH<- list()
community_member <-matrix()
neghbor_list<-list()
count_neighbors<-list()
community_1<-list()
SuperEgo_AZADEH_GRAPH[[2]]=make_ego_graph(graph_AZADEH_GRAPH,2,
V(graph_AZADEH_GRAPH)$name[2],
mode = "all",mindist = 0)
Com_AZADEH_GRAPH[[2]] <- cluster_infomap(SuperEgo_AZADEH_GRAPH[[2]][[1]])
community_member<-data.matrix(membership(Com_AZADEH_GRAPH[[2]]))
neghbor_list[2]=ego(graph_AZADEH_GRAPH, order = 1,
nodes = V(graph_AZADEH_GRAPH)$name[2], mode = "all",mindist = 1)
count_neighbors[2]=length(neghbor_list[[2]])
for (k in 1:nrow(community_member))
{
RRR<-cbind(community_member,as.integer(rownames(community_member)[k]))
}
for (n in 1:nrow(RRR))
{
RRR[n,2]<-as.integer(rownames(RRR)[n])
}
for (i in 1: length(neghbor_list[[2]]))
{
for (j in 1:nrow(RRR))
{
if (neghbor_list[[2]][i]==RRR[[j,2]])
{
community_1[i]=RRR[[j,1]]
}
}
}
the problem is with if statements and more specifically when i=3 and j=6 neghbor_list[[2]][3],
RRR[[6,2]] both return 17 but still it gives False it is working fine when i=1 & 2
(Posted solution on behalf of the question author).
The issue is found, it was referring to the indexes, I should have use $name instead after neghbor_list[[2]][3].

After checking condition need to add a column and assign a value

I have a data frame(final1) with few columns
for(i in final1$Total.Tyres)
{
if(final1$Total.Tyres[i] >= 500){
final1$flag_tyres[i]<-1
} else {
final1$flag_tyres[i]<-0
}
}
I need to check if tires are greater than 500 if so need to assign 1 adding a new column flag_tyres
when tried the above code give me below error
Error in if (final1$Total.Tyres[i] >= 500) { :
missing value where TRUE/FALSE needed
You may want to consider vectorizing your code instead of using for to loop over the rows, saves you typing, hassle and is faster:
final1$flag_tyres <- ifelse(final1$Total.Tyres >= 500, 1, 0)
Simple mistake, should be 1:length(final1$Total.Tyres) in the outer loop. Alternatively, you could vectorize the result, as already answered.

How to include logical checks in a custom function

I have written a custom function that performs a mathematical transformation on a column of data with the inputs being the data and one other input (temperature). I would like to have 2 different logical checks. The first one is whether or not any values in the column exceed a certain threshold, because the transformation is different above and below the threshold. The second is a check if the temperature input is above a certain value and in that case, to deliver a warning that values above the threshold are unusual and to check the data.
Right now, I have the function written with a series of if/else statements. However, this a warning that it is only using the first element of the string of T/F statements. A simplified example of my function is as follows:
myfun = function(temp,data) {
if(temp > 34){
warning('Temperature higher than expected')
}
if (data > 50) {
result = temp*data
return(result)
} else if(data <= 50) {
result = temp/data
return(result)
}
}
myfun(temp = c(25,45,23,19,10), data = c(30,40,NA,50,10))
As you can see, because it is only using the first value for the if/else statements, it does not properly calculate the return values because it doesn't switch between the two versions of the transformation. Additionally, it's only checking if the first temp value is above the threshold. How can I get it to properly apply the logical check to every value and not just the first?
-edit-simplified the function per #The_Questioner's suggestion and changed < 50 to <= 50.
The main issue with your code is that you are passing all the values to the functions as vectors, but then are doing single element comparisons. You need to either pass the elements one by one to the function, or put some kind of vectorized comparison or for loop into your function. Below is the for loop approach, which is probably the least elegant way to do this, but at least it's easy to understand what's going on.
Another issue is that NA's apparently need to be handled in the data vector before passing to any of your conditional statements, or you'll get an error.
A final issue is what to do when data = 50. Right now you have conditional tests for greater or less than 50, but as you can see, the 4th point in data is 50, so right now you get an NA.
myfun = function(temp,data) {
result <- rep(NA,length(temp))
for (t in 1:length(temp)) {
if(temp[t] > 34) {
warning('Temperature higher than expected')
if (!is.na(data[t])) {
if (data [t] > 50) {
result[t] <- temp[t]*data[t]
} else if(data[t] < 50) {
result[t] <- temp[t]/data[t]
}
}
} else {
if (!is.na(data[t])) {
if (data[t] > 50) {
result[t] <- temp[t]*data[t]
} else if(data[t] < 50) {
result[t] <- temp[t]/data[t]
}
}
}
}
return(result)
}
Output:
> myfun(temp = c(25,45,23,19,10), data = c(30,40,NA,50,10))
[1] 0.8333333 1.1250000 NA NA 1.0000000

Resources