Recoding based on TRUE or FALSE in another variable

I compute a new variable based on the TRUE / FALSE status of another:

value<-c(2, 4, 5, 8, 2, 3, 1) tf<-c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE) df<-data.frame(value, tf) 

The following code does what I need (half value if "tf" is TRUE) ...

 df$newVals[which(df$tf)]<-df$value[which(df$tf)]/2 df$newVals[which(!df$tf)]<-df$value[which(!df$tf)] 

... but it's too complicated. Is there a simpler approach?

thanks

+4
source share
4 answers

Here's a very simple solution without ifelse :

 df$newVals <- with(df, value / (tf + 1)) 

How it works?

If boolean values ​​are used with mathematical operators (for example, tf ), they are converted to numeric values ​​( FALSE converted to 0 , and TRUE converted to 1 ). Therefore, the tf + 1 command creates a number vector 1 and 2 s. The values ​​in value are divided by the values ​​in this new vector. Division by one does not change the original values.

+8
source

You can do this with ifelse :

 value<-c(2, 4, 5, 8, 2, 3, 1) tf<-c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE) df<-data.frame(value, tf) df$newVals <- with(df, ifelse(tf, value/2, value)) 
+6
source

Using ifelse and transform will do it for you

  transform(df, newVals=ifelse(tf, value/2,value)) value tf newVals 1 2 TRUE 1.0 2 4 FALSE 4.0 3 5 FALSE 5.0 4 8 FALSE 8.0 5 2 TRUE 1.0 6 3 FALSE 3.0 7 1 TRUE 0.5 
+4
source

Slightly different; just update the values ​​you want to change, not all the values, and select them using ifelse() . For instance.

 value<-c(2, 4, 5, 8, 2, 3, 1) tf<-c(TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE) df<-data.frame(value, tf) df <- transform(df, newVals = value) ## task a copy of `value` df[df$tf, "newVals"] <- df[df$tf, "value"] / 2 ## update only ones we want df 

Provision

 > df value tf newVals 1 2 TRUE 1.0 2 4 FALSE 4.0 3 5 FALSE 5.0 4 8 FALSE 8.0 5 2 TRUE 1.0 6 3 FALSE 3.0 7 1 TRUE 0.5 

You can break this down a bit if you don't like all the indexing - just create an ind that contains the row indices, where tf is TRUE :

 df <- transform(df, newVals = value) ind <- with(df, which(tf)) df[ind, "newVals"] <- df[ind, "value"] / 2 df > df value tf newVals 1 2 TRUE 1.0 2 4 FALSE 4.0 3 5 FALSE 5.0 4 8 FALSE 8.0 5 2 TRUE 1.0 6 3 FALSE 3.0 7 1 TRUE 0.5 
+1
source

Source: https://habr.com/ru/post/1444827/


All Articles