How to Use $ and | Logical operators together In R - r

=if(OR([a]="1",AND([b]<=50,[b]>0)),1,0) - Excel Formula
How Can i Write this as an R code:
below is the code which i tried
i = 1
for (i in 1: length(a))
{
if((dataframe$a[i] == 1) || ((dataframe$b[i] <= 50) && (dataframe$b[i}> 0)))
{dataframe$c[i] <- as.numeric(1);}
else
{dataframe$c[i] <- as.numeric(0);}
}
}
I get the following Errors:
Error: unexpected numeric constant in:
Error: unexpected 'else' in " else
Error: unexpected numeric constant in "
Error: unexpected '}' in "}"

You can try
within(dat, c <- ((0 < b & b <= 50 ) | a == 1) + 0 )
data
set.seed(25)
dat <- data.frame(a=sample(1:5, 100, replace=TRUE),
b= sample(-10:100, 100, replace=TRUE))

There was a "typo" in dataframe$b[i} and one extra }.
So, sample data from #akrun:
set.seed(25)
dat <- data.frame(a=sample(1:5, 100, replace=TRUE),
b= sample(-10:100, 100, replace=TRUE))
Code:
i = 1
for (i in 1: length(dat$a)){
if((dat$a[i] == 1) || ((dat$b[i] <= 50) && (dat$b[i]> 0))){
dat$c[i] <- as.numeric(1)
} else {
dat$c[i] <- as.numeric(0)
}
}
Also works with single operator:
i = 1
for (i in 1: length(dat$a)){
if((dat$a[i] == 1) | ((dat$b[i] <= 50) & (dat$b[i]> 0))){
dat$c[i] <- as.numeric(1)
} else {
dat$c[i] <- as.numeric(0)
}
}
See the diference between single and double operators here

Related

R next prime number Inclusive of start

I have the below existing code in R. The code prints the next immediate prime number. I want to consider inclusive of starting number
np <- function(x){
if (x==1L | x==2L) {return(2L)}
else {
temp <- x+1
test <- 2:x
while( any( (temp %% test) == 0 ) ){
temp <- temp+1
}
temp
} }
Eg.. np(7) returns 11. But expected output is 7.
Try the code below (following a similar idea in the answer here)
np <- function(x) {
p <- x
repeat {
if (p %in% c(2, 3) | all(p %% ceiling(sqrt(2:p)) != 0)) {
return(p)
}
p <- p + 1
}
}
and you will see
> np(2)
[1] 2
> np(3)
[1] 3
> np(4)
[1] 5
> np(5)
[1] 5
> np(7)
[1] 7
Maybe it's stupid but does this do the trip?
np <- function(x){
if (x==1L | x==2L) {return(2L)}
else {
x= x-1
temp <- x+1
test <- 2:x
while( any( (temp %% test) == 0 ) ){
temp <- temp+1
}
temp
} }
You are testing numbers above x only by calling temp <- x+1. Here is a version that should work with minimal changes to your code:
np <- function(x){
if (x==1L | x==2L) {return(2L)}
else {
temp <- x
test <- 2:(x - 1)
while( any( (temp %% test) == 0 ) ){
temp <- temp+1
}
temp
} }

R - for loop error: "Unexpected '}' in '}'"

here is the code for a simulation I'm trying to run:
n_draws <- 1000
black <- rep(0, n_draws)
hispanic <- rep(0, n_draws)
asian <- rep(0, n_draws)
white <- rep(0, n_draws)
cutoff <- c(0.05,0.1,0.25,1)
draws <- runif(n_draws,0,1)
for (i in draws){
if (draws[i] < cutoff[1]){
black[i] <- 1
} else if ((draws[i] >= cutoff[1]) & (draws[i] < cutoff[2])){
hispanic[i] <- 1
} else if ((draws[i] >= cutoff[2]) & (draws[i] < cutoff[3]){
asian[i] <- 1
} else {
white[i] <- 1
}
}
Basically, I want to add a 1 to the corresponding list, conditional on where that number falls in the range (0,1). I'm not sure why this is giving an error. Suggestions?
You're just missing a closing bracket just after cutoff[3], also used seq_along in my example as it's a bit nicer
for (i in seq_along(draws)){
if (draws[i] < cutoff[1]){
black[i] <- 1
} else if ((draws[i] >= cutoff[1]) & (draws[i] < cutoff[2])){
hispanic[i] <- 1
} else if ((draws[i] >= cutoff[2]) & (draws[i] < cutoff[3])){
asian[i] <- 1
} else {
white[i] <- 1
}
}

R: adding logical to sapply

I am trying to run this code:
check_zeros <- function(x) { # WIP
if (x == 0) {
!(df[gsub('\\b0+','',format(as.Date(formation$study_start_dates_list[i]),'%m/%d/%Y')), names(x)] == df[gsub('\\b0+','',format(as.Date(formation$study_end_dates_list[i]),'%m/%d/%Y')), names(x)])
}
}
remove_undesired_stocks2 <- function(n) {
i = 1
listofdfs_filtered <- list()
for (i in 1:n) {
a <- subset(average_returns, row.names(average_returns) == i)
b <- as.data.frame(sapply(subset(average_returns, row.names(average_returns) == i), function(x) all(x == 0 | is.nan(x) | check_zeros(x) )))
c <- a[, !b]
listofdfs_filtered[[i]] <- c
}
return(listofdfs_filtered)
}
Error comes out as:
Error in if (x == 0) { : missing value where TRUE/FALSE needed
I think it is bc there is a NaN going into x == 0 of the check_zeros function.
Any how I can overcome this? Thanks in advance.
I think I solved it myself:
the check_zero function is constructed in a way which cannot take objects with length > 1. more specifically logic inside if cannot use objects length > 1.
Since I was using a object with length > 1, there was an error
You should use ifelse in this case:
check_zeros <- function(x) {
ifelse(x == 0, (df[gsub('\\b0+','',format(as.Date(formation$study_start_dates_list[i]),'%m/%d/%Y')), names(x)] == df[gsub('\\b0+','',format(as.Date(formation$study_end_dates_list[i]),'%m/%d/%Y')), names(x)]), FALSE)
}
Cheers.

"object 'i' not found" the for loop

I am trying to make a simple for loop, that would add a new column to the existing data frame, by assigning a time class to each observation. I am getting 'object 'i' not found' and not sure where is a mistake. I am not that experienced with R, so thank you for any help!
for (i in 1:nrow(my.data)) {
if(my.data$RTime[i] <= 3600){
my.data$RTimeHour[i] <- 1
}ifelse (my.data$RTime[i] > 3601 & my.data$RTime[i] < 7200){
my.data$RTimeHour[i] <- 2
}esle {
my.data$RTimeHour[i] <- 3
}
}
I think you can simply use a nested ifelse statement:
my.data$RTimeHour <- ifelse(my.data$RTime <= 3600, 1,
ifelse(my.data$RTime > 3600 & my.data$RTime <= 7200, 2, 3))
The error is probably coming from the ifelse() you have:
for (i in 1:nrow(my.data)) {
if(my.data$RTime[i] <= 3600){
my.data$RTimeHour[i] <- 1
}ifelse (my.data$RTime[i] > 3601 & my.data$RTime[i] < 7200){
my.data$RTimeHour[i] <- 2
}esle {
my.data$RTimeHour[i] <- 3
}
}
Try this instead:
if(my.data$RTime[i] <= 3600){
my.data$RTimeHour[i] <- 1
}else if(my.data$RTime[i] > 3601 & my.data$RTime[i] < 7200){
my.data$RTimeHour[i] <- 2
}else {
my.data$RTimeHour[i] <- 3
}
}
ifelse vectorizes how the problem, so ifelse(x[i]) will try to refer to something outside of the loop.
Vectorized with tidyverse we can just do:
library(tidyverse)
my.data %>% mutate(RTimeHour = case_when(
RTime <= 3600 ~ 1,
RTime < 7200 ~ 2,
TRUE ~ 3)
)

How to handle multiple conditions in 1 if statement?

I am comparing a 20-day moving average against a 50-day, 100-day 200-day and 333-day. The condition is essentially just
if(20MA > 50MA > 100MA > 200MA > 333MA) {
return TRUE
} else{
FALSE
}
Is there a way in R to handle this without multiple nested if statements?
if(tail(MA_20,n=1) > tail(MA_50,n=1) > tail(MA_100,n=1) > tail(MA_200,n=1) > tail(MA_333,n=1)) {
score[1] <- 1
} else{
score[1] <- -1
}
Use && (see help("&") for other logical operators)
if (tail(MA_20,n=1) > tail(MA_50,n=1) &&
tail(MA_50,n=1) > tail(MA_100,n=1) &&
tail(MA_100,n=1) > tail(MA_200,n=1) &&
tail(MA_200,n=1) > tail(MA_333,n=1)) {
score[1] <- 1
} else {
score[1] <- -1
}
The if statement will return true if all four of those comparisons are true.
The ifelse function might be helpful for you in speeding up your code as it helps vectorize comparisons.
The following way seems more complicated but is more flexible. It first gets all variables named after the pattern "MA_" and sapply the tail to extract the last element. Then uses diff to see if they are in decreasing order.
First make up some data.
library(zoo)
set.seed(1234) # Reproducible results
n <- 1e3
x <- rnorm(n)
MA_20 <- rollmean(x, k = 20)
MA_50 <- rollmean(x, k = 50)
MA_100 <- rollmean(x, k = 100)
MA_333 <- rollmean(x, k = 333)
Now the problem.
score <- NULL
ma <- stringr::str_sort(ls(pattern = "^MA_"), numeric = TRUE)
MA_last <- sapply(ma, function(m) tail(get(m), n = 1))
score[1] <- if(all(diff(MA_last) > 0)) 1 else -1

Resources