How can I transform an ifelse string to a table of equivalence values in R
I have several strings containing ifelse conditional text that I would like to parse and report. In order for non-R experts to understand it, I would like to be able to transform them into a table or something more understandable.
For example:
ifelse(sc19 != "" & sc19 != "1",
ifelse(sc21 == "1", "1",
ifelse(sc22 == "1", "2",
ifelse(sc23 == "1", "3",
ifelse(sc24 == "1", "4",
ifelse(sc25a == "1", "5", "6")
)
)
)
),
""
)
I tried to use str_split with regex to separate from commas, but it is impossible. I'm not sure if there is already a solution for this.
What I would expect to get is the following:
Conditionals | Results |
---|---|
sc19 != "" & sc19 != "1" |
"" |
sc21 == "1" |
"1" |
sc22 == "1" |
"2" |
sc23 == "1" |
"3" |
sc24 == "1" |
"4" |
sc25a == "1" |
"5" |
Not sc25a == "1" |
"6" |
All others | "" |
Assuming:
some_str
[1] "ifelse(sc19 != \"\" & sc19 != \"1\","
[2] "ifelse(sc21 == \"1\", \"1\","
[3] "ifelse(sc22 == \"1\", \"2\","
[4] "ifelse(sc23 == \"1\", \"3\","
[5] "ifelse(sc24 == \"1\", \"4\","
[6] "ifelse(sc25a == \"1\", \"5\", \"6\")"
# as data or
ifel_stk <- quote(ifelse(sc19 != "" & sc19 != "1",
ifelse(sc21 == "1", "1",
ifelse(sc22 == "1", "2",
ifelse(sc23 == "1", "3",
ifelse(sc24 == "1", "4",
ifelse(sc25a == "1", "5", "6")
)
)
)
),
""
))
ifel_stk
ifelse(sc19 != "" & sc19 != "1", ifelse(sc21 == "1", "1", ifelse(sc22 ==
"1", "2", ifelse(sc23 == "1", "3", ifelse(sc24 == "1", "4",
ifelse(sc25a == "1", "5", "6"))))), "")
and considering the rather cumbersome regex on the simplest line "ifelse(sc21 == \"1\", \"1\","
:
as.character(ifelse(grep('(?:sc\\d.{2,3}\\==)\\s(\"1\")',some_str[2], perl = TRUE), grep('(?:sc\\d.{2,3}\\==)\\s(\"1\")', some_str[2], perl = TRUE),
grep('(?:sc\\d.{2,3}\\==)\\s(\"1\"),\\s(\"1\"),)', some_str[2], perl = TRUE)[2]))
[1] "1"
it might be worth considering keeping this numeric. it can be split on a little more that the ,
strsplit(as.character(ifel_stk), split =', i')
[[1]]
[1] "ifelse"
[[2]]
[1] "sc19 != \"\" & sc19 != \"1\""
[[3]]
[1] "ifelse(sc21 == \"1\", \"1\""
[2] "felse(sc22 == \"1\", \"2\""
[3] "felse(sc23 == \"1\", \"3\""
[4] "felse(sc24 == \"1\", \"4\""
[5] "felse(sc25a == \"1\", \"5\", \"6\")))))"
[[4]]
character(0)
The inclination of ifelse(
, even nested is to resolve to the first TRUE condition, in spite of the number of opportunities to traverse the nesting:
report3$values[1]
[1] "3" # a value for sc19
Results <- vector(mode = 'character', length = 6L)
for(i in 1:length(Results)){
Results[i] <- ifelse(report3$values[1] != "" & report3$values[1] != "1",
ifelse(report3$values[2] != "1", "1",
ifelse(report3$values[3] == "1", "2",
ifelse(report3$values[4] != "1", "3",
ifelse(report3$values[5] != "1", "4",
ifelse(report3$values[6] != "2", "5", "6")[i]
)
)
)
),
""
)
}
Results
[1] "2" "2" "2" "2" "2" "2"
each ifelse(
can be demonstrated to behave reliably, left to itself
ifelse(report3$values[1] != "" & report3$values[1] != "1", 'rejoice', '')
[1] "rejoice"
Nesting is tricky, has been said to lead to madness, so best avoided if possible.
report3
that could be used to create your informational report
dput(report3)
structure(list(values = c("3", "1", "1", "1", "1", "1", "2",
"42", NA), Conditionals = c("sc19 != \"\" & sc19 != \"1\"", "sc21 == \"1\"",
"sc22 == \"1\"", "sc23 == \"1\"", "sc24 == \"1\"", "sc25a == \"1\"",
"sc25a.1 != \"1\"", "sc19 == \"42\"", NA), Results = c("1", "1",
"1", "1", "1", "1", "1", "1", "1")), row.names = c("sc19", "sc21",
"sc22", "sc23", "sc24", "sc25a", "sc25a.1", "sc19.1", "9"), class = "data.frame")
report3
values Conditionals Results
sc19 3 sc19 != "" & sc19 != "1" 1
sc21 1 sc21 == "1" 1
sc22 1 sc22 == "1" 1
sc23 1 sc23 == "1" 1
sc24 1 sc24 == "1" 1
sc25a 1 sc25a == "1" 1
sc25a.1 2 sc25a.1 != "1" 1
sc19.1 42 sc19 == "42" 1
9 <NA> <NA> 1
from a prior run, with ifelse(report3$values[2] == "1", "1",
, just update Results
one at a time.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.