David Mitchell
David Mitchell

Reputation: 41

for loop, new column, length > 1, in R

I did a little searching and couldn't find anything exactly like my issue. I've done almost the exact same loop many times before, except it's usually more like "Make X (a factor) whenever you have Y (some other factor)".

Here's my code:

 for(i in 1:nrow(age_cont)){
      if(age_cont$Choice[i] == 1){
        age_cont$Rank[i] = "Never"
      }
      else if(age_cont$Choice[i] == 2){
        age_cont$Rank[i] = "Sometimes"
      }
      else if(age_cont[i] == 3){
        age_cont$Rank[i] = "Frequently"
      }
      else {
        age_cont$Rank[i] = "Always"
      }
    }

But I get this error:

> Error in `[.data.frame`(age_cont, i) : undefined columns selected
In addition: Warning messages:
1: In if (age_cont[i] == 3) { :
  the condition has length > 1 and only the first element will be used
2: In if (age_cont[i] == 4) { :
  the condition has length > 1 and only the first element will be used
3: In if (age_cont[i] == 3) { :
  the condition has length > 1 and only the first element will be used
4: In if (age_cont[i] == 4) { :
  the condition has length > 1 and only the first element will be used
> 

The Choice variable is ordinal (1-4), and I'm trying to create a new column that's parallel to that, but with names instead of numbers. I've tried changing the Choice variable to a factor and rerunning the loop, and even tried simply to rename each number to a name (within the same column) also, but that didn't work either.

Any thoughts?

Upvotes: 0

Views: 410

Answers (3)

FlorianGD
FlorianGD

Reputation: 2436

This is an answer that allows you to drop the for loop and the several ifs by doing a join with a table that gives you the rank. I do a left join and then fill the na's so as to mimic the else clause.

library(tibble)
library(dplyr)
library(tidyr)

set.seed(1)
df <- tibble(Choice = sample(1:4, 10, replace = TRUE))

transco <- tribble( ~Choice, ~Rank,
1, "Never",
2, "Sometimes",
3, "Frequently")

df %>% left_join(transco, by = "Choice") %>%
    replace_na(list(Rank = "Always"))
# A tibble: 10 x 2
   Choice       Rank
    <dbl>      <chr>
1       2  Sometimes
2       2  Sometimes
3       3 Frequently
4       4     Always
5       1      Never
6       4     Always
7       4     Always
8       3 Frequently
9       3 Frequently
10      1      Never

Upvotes: 1

Kalees Waran
Kalees Waran

Reputation: 659

use everywhere

age_cont$Choice[i] %in% #your_number

instead of

age_cont$Choice[i] == #your_number

Also, change age_cont[i] == 3 to age_cont$Count[i] %in% 3

This should solve your problem.

Upvotes: 0

kangaroo_cliff
kangaroo_cliff

Reputation: 6222

Seems like there is an error in the line

   else if(age_cont[i] == 3){

I think you meant

   else if(age_cont$Choice[i] == 3){  

This should explain the error message.

Upvotes: 1

Related Questions