Ally D
Ally D

Reputation: 165

For loop with conditional if statements

I can't figure out what is wrong with this code. I have a dataframe called Fish. I want to add a column called CombineMe that is default 0. The value would change to 501 if it meets the two criteria (either the data source = A & sample method = visual then it would equal 501 and also if the data source = B & taxon code is the three EJ, EL or RV). I can't quite figure out where I'm going wrong. I've tried adjusting where the [i] are and adding commas...

for(i in 1:length(Fish)) {
Fish$CombineMe <- 0 
if (Fish$data_source == "A" & Fish$sample_method == "visual") {
  Fish$CombineMe [i] <- 501
} else if (Fish$data_source == "B" & Fish$taxon_name == c("EJ", "EL", "RV")){
  Fish$CombineMe [i] <- 501
}}

Here's a condensed example of what Fish looks like:

Fish <- data.frame ("data_source"=c("A", "A", "B", "C", "C", "D", "D"), "sample_method"= c("visualfish", "fish", "fish", "fish", "fish", "fish", "fish"), 
                  "taxon_name"=c("EJ", "EJ", "RV", "EJ", "RV", "EL", "HR"))

Upvotes: 1

Views: 108

Answers (3)

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521239

This is the offending line of code:

Fish$CombineMe <- 0

You are zeroing out the entire column, for each iteration of the loop. Move this outside and before the loop and it should work.

But R is a vectorized language, and a much better way of making your assignment would not even use a loop at all:

cond1 <- Fish$data_source == 'A' & Fish$sample_method == 'visual'
cond2 <- Fish$data_source == "B" & Fish$taxon_name %in% c('EJ', 'EL', 'RV')
Fish$CombineMe <- ifelse(cond1 | cond2, 501, 0)

Upvotes: 1

addicted
addicted

Reputation: 3051

Normally you need to provide how Fish dataframe looks like. I try to guess based on your given code:

Fish$CombineMe <- 0 
for(i in 1:nrow(Fish)) {

if (Fish$data_source[i] == "A" & Fish$sample_method[i] == "visual") {
  Fish$CombineMe[i] <- 501
} else if (Fish$data_source[i] == "B" & Fish$taxon_name[i] %in% c("EJ", "EL", "RV")){
  Fish$CombineMe [i] <- 501
}}

I don't think you need a loop, though. Here is the alternative method using ifelse.

Fish$CombineMe <- 0
Fish$CombineMe <- ifelse(Fish$data_source == "A" & Fish$sample_method == "visual", 501, Fish$CombineMe)
Fish$CombineMe <- ifelse(Fish$data_source == "B" & Fish$taxon_name %in% c("EJ", "EL", "RV"), 501, Fish$CombineMe)

Upvotes: 1

Alejandro Andrade
Alejandro Andrade

Reputation: 2216

The problem you are having is because everytime you loop you define Fish$CombineMe <- 0 so you are reseting the hole column to cero each time. To fix this:

Fish$CombineMe[i] <- 0 

Upvotes: 0

Related Questions