rdataframer-rownames

Ifelse using rownames in r is treating row numbers not as integers


I have a block of code that look like this:

ParticipantNum <- c(1,2,4,5,7,8,9,10,13,15,16,17,18,22,24,26,27,28,29,30,32,33,35,36,39,41,43,44,45,49,50,53,54)
ParticipantTime <- c(55,54,56,88,54,79,64,52,48,21,54,87,62,35,54,87,96,96,87,53,54,52,32,89,11,28,47,78,22,14,49,75,45)
summary <- data.frame(Number=ParticipantNum,Time=ParticipantTime,Category='')
summary$Category <- ifelse(row.names(summary)<=3,"Dogs","Cats")

I am setting up a dataframe with 3 columns: Number, Time, and Category, where category is Dogs and Cats. I want my dataframe to make rows 1-3 say Dogs and all other rows say Cats. (This is an example for clarity). Somehow, when I do this, it makes rows 1-3 say Dogs, as well as rows 10-29. Rows 4-9 and 30-33 (the last row) say Cats. My intuition says it's treating row 10-29 as being "less than 3" because the first character of the row name is less than 3. I don't know why it would be doing this. I've read through the documentation for rownames and row.names but I don't understand it well enough to fix my problem. I'm new to r and relatively new to coding. Thanks.

enter image description here


Solution

  • The issue is with how row.names works. If you look at the documentation, it is subtle but says:

    Row names of the form 1:n for n > 2 are stored internally in a compact form, which might be seen from C code or by deparsing but never via row.names or attr(x, "row.names").

    And for numeric operations:

    row.names will always return a character vector. (Use attr(x, "row.names") if you need to retrieve an integer-valued set of row names.)

    So your code will work if you use attr(summary, "row.names"), but using as.numeric is probably nicer looking.

    ParticipantNum <- c(1, 2, 4, 5, 7, 8, 9, 10, 13, 15, 16, 17, 18, 22, 24, 26, 27, 28, 29, 30, 32, 33, 35, 36, 39, 41, 43, 44, 45, 49, 50, 53, 54)
    ParticipantTime <- c(55, 54, 56, 88, 54, 79, 64, 52, 48, 21, 54, 87, 62, 35, 54, 87, 96, 96, 87, 53, 54, 52, 32, 89, 11, 28, 47, 78, 22, 14, 49, 75, 45)
    summary <- data.frame(Number = ParticipantNum, Time = ParticipantTime, Category = "")
    # summary$Category <- ifelse(attr(summary, "row.names") <= 3, "Dogs", "Cats")
    summary$Category <- ifelse(as.numeric(row.names(summary)) <= 3, "Dogs", "Cats")
    summary
    #>    Number Time Category
    #> 1       1   55     Dogs
    #> 2       2   54     Dogs
    #> 3       4   56     Dogs
    #> 4       5   88     Cats
    #> 5       7   54     Cats
    #> 6       8   79     Cats
    #> 7       9   64     Cats
    #> 8      10   52     Cats
    #> 9      13   48     Cats
    #> 10     15   21     Cats
    #> 11     16   54     Cats
    #> 12     17   87     Cats
    #> 13     18   62     Cats
    #> 14     22   35     Cats
    #> 15     24   54     Cats
    #> 16     26   87     Cats
    #> 17     27   96     Cats
    #> 18     28   96     Cats
    #> 19     29   87     Cats
    #> 20     30   53     Cats
    #> 21     32   54     Cats
    #> 22     33   52     Cats
    #> 23     35   32     Cats
    #> 24     36   89     Cats
    #> 25     39   11     Cats
    #> 26     41   28     Cats
    #> 27     43   47     Cats
    #> 28     44   78     Cats
    #> 29     45   22     Cats
    #> 30     49   14     Cats
    #> 31     50   49     Cats
    #> 32     53   75     Cats
    #> 33     54   45     Cats
    

    Created on 2024-11-04 with reprex v2.1.1.9000