1

So this is some sample data I have:

signal1   signal2   signal3   
1         0         1        
1         1         1  
1         0         1  
1         0         1  
1         0         1  
1         0         1  
1         0         0 

And I want to add a fourth column, such that whenever signal1==signal2==signal3 are both 1, the new column repeats 1s until signal3 changes from 1 to 0.

So from the above example, I want to generate something like:

signal1   signal2   signal3   signal_generate
1         0         1         0
1         1         1         1
1         0         1         1
1         0         1         1
1         0         1         1
1         0         1         1
1         0         0         0

I'm thinking this would be achieved by an ifelse statement, but I'm having a lot of difficulty over this seemingly simple task. I'm thinking of doing something along the lines of:

signal_generate <- ifelse(data[,1]==data[,2]&data[,3]>0, rep(data[,3]==1), 0)

But I can't figure out how to get signal3 to repeat the correct number of times.

Edit: I'm realizing an ifelse would be silly because it would only look at rows in which the condition signal1 == signal2 == signal3 meet exactly. I'm still terribly stuck, and help would be much appreciated!

Nikitau
  • 371
  • 3
  • 16

1 Answers1

1

With help from Replacing NAs with latest non-NA value

I am not sure the initial conditions are handled correctly.

df <- read.table(text="
signal1   signal2   signal3   
1         0         1        
1         1         1  
1         0         1  
1         0         1  
1         0         1  
1         0         1  
1         0         0
", header=TRUE)

library(zoo)

# apply the logic using RowSums as a shortcut
df$triple <- as.integer((rowSums(df[,1:3])) == 3L)

# detect the change in signal and sett the initial condition
df$signal_change <- ifelse(df$triple == 1L, 1L, ifelse(df$signal3 == 0L, 0, NA))
df$signal_change[1] <- df$triple[1]

# generate the signal by carryign forward the changes
df$signal_generate <- na.locf(df2$signal_change, na.rm=FALSE)
df$signal_generate[1] <- df$signal_change[1]

df

#   signal1 signal2 signal3 triple signal_change signal_generate
# 1       1       0       1      0             0               0
# 2       1       1       1      1             1               1
# 3       1       0       1      0            NA               1
# 4       1       0       1      0            NA               1
# 5       1       0       1      0            NA               1
# 6       1       0       1      0            NA               1
# 7       1       0       0      0             0               0
Community
  • 1
  • 1
Andrew Lavers
  • 4,328
  • 1
  • 12
  • 19
  • Thanks. Quick question, does `as.integer((rowSums(df[,1:3])) == 3L` only work with tables, or can this be used with `data.frame`? I tried implementing this on my actual data and it returned `0` for everything. – Nikitau Apr 13 '17 at 15:10
  • from the help for rowSums "...for numeric arrays (or data frames)". I don't have an example of your data -- best to use 'dput' and and add the to the question. My example is a data frame. i suggest you debug by executing smallest bit of code from innermost to outermost and examine results. Also check for your parentheses – Andrew Lavers Apr 13 '17 at 16:53