1

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"))
5
  • Try to use 1 of the Fish column instead of the whole dataframe itself. length(Fish$column). or use 1:nrow(Fish) Commented Nov 16, 2017 at 2:01
  • just tried that, getting the same result. I get the column CombineMe, but it has only 0 it isn't filling in any 501. This is the warning I get if (Fish$data_source == "sni" & Fish$taxon_name == ... : the condition has length > 1 and only the first element will be used Commented Nov 16, 2017 at 2:04
  • @AllyD could you show some data? Commented Nov 16, 2017 at 2:05
  • FIsh$Combine <- ifelse(Fish$data_source == "A" & Fish$sample_method == "visual", 501, ifelse(Fish$data_source == "B" & Fish$taxon_name == c("EJ", "EL", "RV"), 501, 0)) Commented Nov 16, 2017 at 2:09
  • First thing, Fish$CombineMe <- 0 should be out of the loop. Second thing, compare using i index. For example, Fish$data_source[i] == "A" & Fish$sample_method[i] == "visual". Third thing change your second if statement to Fish$taxon_name[i] %in% c("EJ", "EL", "RV") and last but not the least if you could show a reproducible example there are definitely better ways to do it. Commented Nov 16, 2017 at 2:09

3 Answers 3

1

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)
Sign up to request clarification or add additional context in comments.

1 Comment

thanks so much this worked great! firstly, I definitely didn't realize I was just zeroing it out. and I love the more simplified ifelse. I'm super new to R so learning something new everyday!
1

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)

Comments

0

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 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.