So I've been trying to figure out what is wrong with my if-condition, but I am getting nowhere. I am still new to R, so maybe I am not understanding some very basic concept here?
I have a dataframe (dc) to which I appended a column with logical "FALSE". Now I want to change each FALSE into a TRUE based on the values in two columns of dc (dc$Probe and dc$Resp) that I specified using regexpr().
What it does so far is that, for both if-conditions, it changes each FALSE into TRUE regardless of the values in column 5 of dc. When I run the if-conditions seperately, I can see that they seem to be working fine on the OR-part of the condition, meaning the code only generates TRUE when the strings in dc$Probe match one of the strings specified in the OR-part. However, the AND-part seems to be ignored? Thus, when I run the complete code, I get a column with only TRUE, which is not what I want.
Edit: I should get a TRUE only if the string in Probe ends in a certain pattern (as specified in either of the two if conditions I wrote) and if the corresponding value in Resp is a "100" for the patterns specified in my first condition or a "200" for the patterns specified in my second condition. Thus, for strings ending in (sg|s|w1|w3|s1|s2), Resp must be "100" to get a TRUE and for strings ending in (\d\dg|\d\d), Resp must be "200" to get a TRUE. All other cases should be FALSE. For example, if a string ends in s1 and the corresponding value in Resp is 200, the code should return FALSE.
Edit: Some example data:
>dc<-data.frame(Subject=rep("SN",6), item.c=(1:6), Stim=c("XYZc02s03","XYZc01s30","XYZc02s29", "XYZc01s38", "XYZc02s11", "XYZc06w21"), Probe=c("XYzf02s03","XYZf01s30g","XYZf02s29w1","XYZf01s38sg","XYZf02s11s","XYZv06w21s1"), Resp=c(200, 100, 100, 100, 100, 200))
This is my code:
>dc$Resp<-as.character(dc$Resp) #column 5 in dc
dc$Probe<-as.character(dc$Probe)
dc$correct_response <- FALSE
for (i in 1:nrow(dc)) {
if (regexpr("^.*sg$", dc$Probe[i])==1 || regexpr("^.*s$", dc$Probe[i])==1 || regexpr("^.*w1$", dc$Probe[i])==1 || regexpr("^.*w3$", dc$Probe[i])==1 || regexpr("^.*s1$", dc$Probe[i])==1 || regexpr("^.*s2$", dc$Probe[i])==1 && dc[i,5]=="100") {(dc$correct_response[i]<- TRUE)}
if (regexpr("^.*\\d\\dg$", dc$Probe[i])==1 || regexpr("^.*\\d\\d$", dc$Probe[i])==1 && dc[i,5]=="200") {(dc$correct_response[i]<- TRUE)}
}
Is there something wrong with the regular expressions I am using? I checked them with glob2rx() and it seems like they are ok...Is my use of "OR" (||) or/and "AND" (&&) incorrect? How do I implement the AND-part properly? I have also tried the following code for the AND-part, but it didn't change anything:
regexpr("200", dc$Resp[i])==1
I read the R-help on regular expressions and control flow, but I still don't see what I am doing wrong. Consulting other webpages on logical expressions did not help me either.
Please help!
Im wondering if it can all be reduced to the following:
dc<- read.table(header=T,text="Subject item.c Stim Probe Resp
SN 1 XYZc02s03 XYzf02s03 200
SN 2 XYZc01s30 XYZf01s30g 100
SN 3 XYZc02s29 XYZf02s29w1 100
SN 4 XYZc01s38 XYZf01s38sg 100
SN 5 XYZc02s11 XYZf02s11s 100
SN 6 XYZc06w21 XYZv06w21s1 200")
cond1<-regexpr("^.*(sg|s|w1|w3|s1|s2)$", dc$Probe)==1 & dc$Resp==100
cond2<-regexpr("^.*(\\d\\dg|\\d\\d)$", dc$Probe)==1 & dc$Resp==200
dc$correct_response<-cond1|cond2
For one thing, you are missing a logical operator between the 2nd and 3rd clauses of your first if statement.
Related
I'm trying to highlight a row if the number of blank cells between say, C1 and E1 = 3
and then copy this down for every row.
I've tried using:
=IF(COUNTBLANK($C1:$E1)=3)
But it's not working, can anybody help?
Under conditional formatting, your formula should be the following based on what you've given. The reason is conditional format is trying to see the result as TRUE or False. The IF statement is trying to tell the computer what to do when it's TRUE or FALSE.
COUNTBLANK($C1:$E1)=3
if you want to use IF you will need to do it like this:
=IF(COUNTBLANK($C1:$E1)=3, 1)
I'm having a problem that seems way more easy than it is. I think its more of an algorithmic problem than a coding one.
EDIT:
Imagine you have a database with a name and N boolean parameters, like if the person is blonde or not, if the person likes baseball or not, if person have a smartphone or not etc...
How could you print the name of someone that likes baseball AND is blonde, but doesn't matter if any of the other N parameters are true of false? How can I do that without having to write a test for every single of the (N^2)-1 possibilities?
I created a dictionary that maps a string to a struct with 4 boolean variables and some strings.
I want the user to select which booleans are important to them and return only the information that is true for all variable that he chose.
Something like a checkbox which you can use to filter a column in excel.
For instance if a user chose variables 1 and 2, I would like to know if there is a better way to return the result rather than testing every one of the 16 possibilities, like:
void filter(map<string, Mystruct> Mydictionary, bool bool1, bool bool2, bool bool3, bool bool4){
if(bool1 == true && bool2 == true && bool3 == false && bool4==false){
cout << Mydictionary.bool1Info << Mydictionary.bool2Info
if(bool1 == true && bool2 == false && bool3 == false && bool4==false)
...
Even more, for me its only important to test the booleans that the user picked up, so even if he didn't choose boolean3, it's not important to test if its true or false.
Any ideas?
I would be very glad if anyone could help me with this one
I can help you with your algorithm part ,
instead of checking all 16 possibilities just check 4 conditions separately for bool1,2,3,4 and print their info if they are true.
This way you can complete your task with only 4 if statements.
Hope this answers your query.
/* FLAG_MISMATCH_PAID*/
(CASE
WHEN t1.Paid=t2.PAID_AMT THEN "TRUE"
ELSE "FALSE"
END) AS FLAG_MISMATCH_PAID
This works when I am using other variables, but for some reason I am getting incorrect TRUE/FALSE results when I use this code. I thought maybe there was some issues with numbers beyond the hundreds unit so I tried using round (x, .01), but correcting for that made no difference.
Why would two numbers that are exactly the same still give me a "FALSE" result? (i.e. t1.Paid = $106,115.23 and t2.PAID_AMT = $106,115.23, and it is flagged as FALSE, yet t1.Paid =$57,242.11 and t2.PAID_AMT = $57,242.11 is TRUE)
I'm am exploring methods of giving scores to different datapoints within a dataset. These points come from a mix of numbers and text string attributes looking for certain characteristics, e.g. if Col. A contains more than X number of "|", then give it a 1. If not, it gets a 0 for that category. I also have some that give the point when the value is >X.
I have been trying to do this with =IF, for example, =IF([sheet] = [Text], "1","0").
I can get it to give me 1 or 0, but I am unable to get a point total with sum.
I have tried changing the formatting of the text to both "number", "plain text", and have left it as automatic, but I can't get it to sum. Thoughts? Is there maybe a better way to do this?
FWIW - I'm trying to score based on about 12 factors.
Best,
Alex
The issue here might be that you're having the cell evaluate to either the string "0" or the string "1" rather than the number 0 or the number 1. That would explain why you're seeing the right things but the math isn't coming out right - the cell contents look like numbers, but they're really text, which the summation would then ignore.
One option would be to drop the quotation marks and write something like this:
=IF(condition, 1, 0)
This has the condition evaluate to 1 if it's true and 0 if it's false.
Alternatively, you could write something like this:
=(condition) * 1
This will take the boolean TRUE or FALSE returned by condition and convert it to either the numeric value 1 (true) or the numeric value 0 (false).
I can't figure out why this if statement won't work.
I have a DateTime field DATEFROM and a String parameter (it HAS to be String) periodEnd.
I would like to calculate percentages depending if these two dates have 1, 2, 3 or more years difference.
When I use this formula I get either "100%" or "-" and never the other two options. It's like CR calculates the first IF and if it's true then: "100%" but if it's false, it never checks for the rest of the Else Ifs and goes dirreclty to Else
StringVar percentage:="";
If (cDate({?periodEnd})-{TABLE.DATEFROM})<=1 Then
percentage:="100%"
Else If (cDate({?periodEnd})-{TABLE.DATEFROM})<=2 Then
percentage:="66%"
Else If (cDate({?periodEnd})-{TABLE.DATEFROM})<=3 Then
percentage:="33%"
Else
percentage:="-"
Any idea?
a) I assume you already made sure your periodend format matches with what cdate interprets?
If you just subtract them, Crystal by default returns the number of days between.
Two ways you can do year:
datediff("yyyy",cDate({?periodEnd},{TABLE.DATEFROM})
or
year(cDate({?periodEnd})-year({TABLE.DATEFROM})
b) You've also no doubt accounted for when your {TABLE.DATEFROM} is greater than cDate({?periodEnd} and you have a negative result?
Not sure if the following is the behavior you would want, but I'm throwing it in for your information
ABS(datediff("yyyy",cDate({?periodEnd},{TABLE.DATEFROM}))
**make sure you check the help file for the datediff codes ("yyyy" etc) as they are not quite instinctive and can trip you up when you think you're using the obvious one