简体   繁体   中英

How can I transform an ifelse string to a table of equivalence values in R

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM