Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

R ifelse loop on unique values always resolves FALSE

I am newish to R and having trouble with a for loop over unique values.

with the df:

id = c(1,2,2,3,3,4) 
rank = c(1,2,1,3,3,4) 
df = data.frame(id, rank)     

I run:

df$dg <- logical(6)

for(i in unique(df$id)){
  ifelse(!unique(df$rank), df$dg ==T, df$dg == F)
}

I am trying to mark the $dg variable as T providing that rank is different for each unique id and F if rank is the same within each id.

I am not getting any errors, but I am only getting F for all values of $dg even though I should be getting a mix.

I have also used the following loop with the same results:

for(i in unique(df$id)){
  ifelse(length(unique(df$rank)), df$dg ==T, df$dg == F)
}

I have read other similar posts but the advice has not worked for my case.

From Comments:

I want to mark dg TRUE for all instances of an id if rank changed at all for a given id. Im looking to say for a given ID which has anywhere between 1-13 instances, mark dg TRUE if rank differs across instances.

like image 421
MattM Avatar asked Apr 26 '26 13:04

MattM


1 Answers


Update: How to identify groups (ids) that only have one rank?


After clarification that OP provided this would be a solution for this particular case:

library(dplyr)
df %>% 
   group_by(id) %>% 
         mutate(dg = ifelse( length(unique(rank))>1 | n() == 1, T, F))

For another data-set that has also an id, which has duplicates but also non-duplicate rank (presented below) this would be the output:

df2 %>% 
   group_by(id) %>% 
         mutate(dg = ifelse( length(unique(rank))>1 | n() == 1, T, F))

#:OUTPUT:

# Source: local data frame [9 x 3] 
# Groups: id [5] 
#  
# # A tibble: 9 x 3 
#      id  rank    dg 
#   <dbl> <dbl> <lgl> 
# 1     1     1  TRUE 
# 2     2     2  TRUE 
# 3     2     1  TRUE 
# 4     3     3 FALSE 
# 5     3     3 FALSE 
# 6     4     4  TRUE 
# 7     5     1  TRUE 
# 8     5     1  TRUE 
# 9     5     3  TRUE

Data-no-2:

df2 <- structure(list(id = c(1, 2, 2, 3, 3, 4, 5, 5, 5), rank = c(1, 2, 1, 3, 3, 4, 1, 1, 3
                )), .Names = c("id", "rank"), row.names = c(NA, -9L), class = "data.frame")



How to identify duplicated rows within each group (id)?


You can use dplyr package:

library(dplyr)
df %>% 
   group_by(id, rank) %>% 
                      mutate(dg = ifelse(n() > 1, F,T))

This will give you:

# Source: local data frame [6 x 3] 
# Groups: id, rank [5] 
#  
# # A tibble: 6 x 3 
#      id  rank    dg 
#   <dbl> <dbl> <lgl> 
# 1     1     1  TRUE 
# 2     2     2  TRUE 
# 3     2     1  TRUE 
# 4     3     3 FALSE 
# 5     3     3 FALSE 
# 6     4     4  TRUE

Note: You can simply convert it back to a data.frame().

A data.table solution would be:

dt <- data.table(df)
dt$dg <- ifelse(dt[ , dg := .N, by = list(id, rank)]$dg>1,F,T)

Data:

df <- structure(list(id = c(1, 2, 2, 3, 3, 4), rank = c(1, 2, 1, 3, 
      3, 4)), .Names = c("id", "rank"), row.names = c(NA, -6L), class = "data.frame")

# > df

#   id rank 
# 1  1    1 
# 2  2    2 
# 3  2    1 
# 4  3    3 
# 5  3    3 
# 6  4    4

N. B. Unless you want a different identifier rather than TRUE/FALSE, using ifelse() is redundant and costs computationally. @DavidArenburg

like image 139
M-- Avatar answered Apr 28 '26 05:04

M--



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!