how to check a number in range

define data set

test <- data.frame(
stringsAsFactors = FALSE,
meastype = c(373, 373, 373, 373, 372, 372, 414, 414, 414, 414),
n=c(250,40,395,41,150,3456,2310.2,334.5,4459.5,2223),
totalcase = c(15, 10, 1, 9, 2500, 356, 30, 29, 40, 10),
note = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
outlier = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
warning = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
)

atype <- 1

if (atype != 5) {

do nothing

test1 <- test
} else {

define Small N if meastype is 373

if (meastype==373){
test1 <- test %>%
mutate(n=ifelse(totalcase==1,totalcase,n)) %>%
mutate(note=ifelse(NaN<n<10,3,note)) %>%
mutate(outlier=ifelse(NaN<n<10,'N',outlier)) %>%
mutate(warning=ifelse(NaN<n<10,4,warning))
} else {
# do nothing
test1 <- test}
}
variable atype controls the program flow . When it was set to 1, I thought that test1 would be generated as same as test. But the program went to 'define small N ' section with error. When it was set to 5, the result was same with same error message: "Error: unexpected '<' in:..... What is the problem and how to fix it? Thanks in advance!

Evaluates to what value?

Does this get to your desired output?

library(dplyr)

test <- data.frame(
  stringsAsFactors = FALSE,
  meastype = c(373, 373, 373, 373, 372, 372, 414, 414, 414, 414),
  n=c(250,40,395,41,150,3456,2310.2,334.5,4459.5,2223),
  totalcase = c(15, 10, 1, 9, 2500, 356, 30, 29, 40, 10),
  note = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  outlier = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
  warning = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
)

atype <- 5

if (atype != 5) {
  # do nothing
  test1 <- test
} else {
  # meastype is not 373
  a = test %>% filter(meastype != 373)
  
  # meastype is 373
  b = test %>% filter(meastype == 373) %>%
    mutate(n=ifelse(totalcase==1,totalcase,n)) %>%
    mutate(note=ifelse(!is.na(n) & n < 10,3,note)) %>%
    mutate(outlier=ifelse(!is.na(n) & n < 10,'N',outlier)) %>%
    mutate(warning=ifelse(!is.na(n) & n < 10,4,warning))
  
  test1 = bind_rows(b, a)
}

test
#>    meastype      n totalcase note outlier warning
#> 1       373  250.0        15    0      NA       0
#> 2       373   40.0        10    0      NA       0
#> 3       373  395.0         1    0      NA       0
#> 4       373   41.0         9    0      NA       0
#> 5       372  150.0      2500    0      NA       0
#> 6       372 3456.0       356    0      NA       0
#> 7       414 2310.2        30    0      NA       0
#> 8       414  334.5        29    0      NA       0
#> 9       414 4459.5        40    0      NA       0
#> 10      414 2223.0        10    0      NA       0
test1
#>    meastype      n totalcase note outlier warning
#> 1       373  250.0        15    0    <NA>       0
#> 2       373   40.0        10    0    <NA>       0
#> 3       373    1.0         1    3       N       4
#> 4       373   41.0         9    0    <NA>       0
#> 5       372  150.0      2500    0    <NA>       0
#> 6       372 3456.0       356    0    <NA>       0
#> 7       414 2310.2        30    0    <NA>       0
#> 8       414  334.5        29    0    <NA>       0
#> 9       414 4459.5        40    0    <NA>       0
#> 10      414 2223.0        10    0    <NA>       0

Created on 2023-01-19 with reprex v2.0.2.9000

1 Like

Is it a missing value? Confused in R

NaN is not a number and can't be compared with a number

a = 42
b <- 137
NaN < a # NA
NaN < a < b # Error, does not parse second <
(NaN < a) < b # left evaluates to NA
NA < b # same here
1 Like

Got it. that was part of the error message, but couldn't get it at that time. Thank you.

Another question is that if the atype is 1, the program shouldn't get into the otherwise logic, but it did and gave the same error message. Why is that? How does the if... else syntax like this work in R?

Riffing on @scottyd22 's reprex

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

test <- data.frame(
  stringsAsFactors = FALSE,
  meastype = c(373, 373, 373, 373, 372, 372, 414, 414, 414, 414),
  n = c(250, 40, 395, 41, 150, 3456, 2310.2, 334.5, 4459.5, 2223),
  totalcase = c(15, 10, 1, 9, 2500, 356, 30, 29, 40, 10),
  note = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
  outlier = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA),
  warning = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
)

index_dat <- function(x, y) which(x[1] == y)
index_dat(test,373)
#> [1] 1 2 3 4
make_second <- function(x, y) {
  # meastype value is specified by parameter y in
  # data frame specified by parameter x
  a <- x[index_dat(x, y), ]
  b <- x[-index_dat(x, y), ]
  b |>
    dplyr::mutate(n = ifelse(totalcase == 1, totalcase, n)) |>
    dplyr::mutate(note = ifelse(!is.na(n) & n < 10, 3, note)) |>
    dplyr::mutate(outlier = ifelse(!is.na(n) & n < 10, "N", outlier)) |>
    dplyr::mutate(warning = ifelse(!is.na(n) & n < 10, 4, warning))
  return(dplyr::bind_rows(a, b))
}

make_second(test, 373)
#>    meastype      n totalcase note outlier warning
#> 1       373  250.0        15    0      NA       0
#> 2       373   40.0        10    0      NA       0
#> 3       373  395.0         1    0      NA       0
#> 4       373   41.0         9    0      NA       0
#> 5       372  150.0      2500    0      NA       0
#> 6       372 3456.0       356    0      NA       0
#> 7       414 2310.2        30    0      NA       0
#> 8       414  334.5        29    0      NA       0
#> 9       414 4459.5        40    0      NA       0
#> 10      414 2223.0        10    0      NA       0

interesting.... not straightforward, but elegant. it seems that R isn't 'sensitive ' to general if...else syntax, and I should use to R way handling condition logic. Thank you very much. Does the symbol |> work the same as %>%?

Not quite, sometimes it doesn't implicitly pass the object identity, in which case

|> something(x = _)

where x is a literal.

I could have made the stuff following the last pipe simpler, but I had not the time.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.