I wonder how for loop
can be used at once without non-numeric error
. I would like to make multiple character values in a vector Nums
, using for loop
.
But after the third line, the vector becomes chr
so cannot continue the rest. This comes out to be same even when I use if loop
or while loop
... Can someone give a hint about this?
for(n in 1:30){
Nums<-1:n
Nums[Nums%%2==0 & Nums%%3==0]<-"OK1"
Nums[Nums%%2==0 & Nums%%3!=0]<-"OK2"
Nums[Nums%%2!=0 & Nums%%3==0]<-"OK3"
Nums[Nums%%2!=0 & Nums%%3!=0]<-n
}
Error in Nums%%2 : non-numeric argument to binary operator
CodePudding user response:
I don't think the loop is actually doing what you want it to do. You are replacing Nums
at every iteration, so nothing is actually being saved. Maybe you don't actually want a loop.
Nums <- 1:30
x <- 1:30
dplyr::case_when(
Nums%%2==0 & x%%3==0 ~ "OK1",
Nums%%2==0 & x%%3!=0 ~ "OK2",
Nums%%2!=0 & x%%3==0 ~ "OK3",
Nums%%2!=0 & x%%3!=0 ~ as.character(x)
)
#> [1] "1" "OK2" "OK3" "OK2" "5" "OK1" "7" "OK2" "OK3" "OK2" "11" "OK1"
#> [13] "13" "OK2" "OK3" "OK2" "17" "OK1" "19" "OK2" "OK3" "OK2" "23" "OK1"
#> [25] "25" "OK2" "OK3" "OK2" "29" "OK1"
CodePudding user response:
Character and numeric values can't coexist in a vector*. As @Ands. points out, you don't really need a loop for this. If you want to avoid case_when
(which is from the dplyr
package, part of the "tidyverse"), you can do:
n <- 30
Nums <- 1:n
x <- as.character(Nums)
x[Nums%%2==0 & Nums%%3==0]<-"OK1"
x[Nums%%2==0 & Nums%%3!=0]<-"OK2"
x[Nums%%2!=0 & Nums%%3==0]<-"OK3"
You don't need the final statement because the remaining elements were already set to the corresponding numeric values.
If you want to use a for loop and replace as you go, you could convert the vector to a list:
Nums <- 1:n
Nums <- as.list(Nums)
for (i in 1:n) {
if (i%%2==0 & i%%3==0) Nums[[i]] <- "OK1"
if (i%%2==0 & i%%3!=0) Nums[[i]] <- "OK2"
if (i%%2!=0 & i%%3==0) Nums[[i]] <- "OK3"
}
unlist(Nums)
* Technically they can't coexist in an atomic vector — lists are vectors too ...