Вопрос:

R: как удалить данные в подмножестве в цикле

r dataframe

41 просмотра

2 ответа

2132 Репутация автора

df <- data.frame(id = c(1, 2, 3, 3, 3, 4), gender = c("Male", "Female", "Both", "Male", "Female", "Female"))
ids <- unique(df$id)

> df
  id gender
1  1   Male
2  2 Female
3  3   Both
4  3   Male
5  3 Female
6  4 Female 

Для каждого уникального id, я хочу , чтобы убедиться , что , если соответствующая genderей является Both, Maleи Female, то мне нужно удалить строку , соответствующую Both. Другими словами, мой желаемый результат:

> df
  id gender
1  1   Male
2  2 Female
3  3   Male
4  3 Female
5  4 Female 

Я попытался написать цикл:

  1. подмножество в dfВ idи хранить каждое подмножество в список под названиемsub

  2. в каждом из них subпроверьте, содержат ли пол «оба», «мужской» и «женский»

  3. если это так, удалите строку с пол = "Оба"

  4. повторно объединить data.frame

Тем не менее, следующий код на самом деле не работает и очень неуклюжий ... Мне интересно, есть ли более простой способ с использованием group_byin dplyr?

sub <- list()
for(i in 1:length(ids)){
  sub[[i]] <- subset(df, id %in% ids[i])
  if(all(grepl(sub[[i]]$gender, c("Both", "Male", "Female")))){
    sub[[i]] <- sub[[i]][-which(sub[[i]]$gender == "Both"), ]
  }else sub[[i]] = sub[[i]]
}
Автор: Adrian Источник Размещён: 08.11.2017 11:32

Ответы (2)


2 плюса

161791 Репутация автора

Решение

Используя dplyr

df %>% 
    group_by(id) %>% 
    mutate(A = ifelse(length(unique(gender)) >= 3 & gender == 'Both', F, T)) %>% 
    filter(A) %>% 
    select(-A)
# A tibble: 5 x 2
# Groups:   id [4]
     id gender
  <dbl>  <chr>
1     1   Male
2     2 Female
3     3   Male
4     3 Female
5     4 Female
Автор: WeNYoBen Размещён: 08.11.2017 11:43

0 плюса

1275 Репутация автора

В дополнение к решению Tidyverse, здесь решение с использованием lapply:

result <- lapply(ids,function(x){
    tmp <- df[df$id == x,]
    if(all(c("Both","Male", "Female") %in% tmp$gender)){
        tmp <- tmp[tmp$gender != "Both",]
    }
    return(tmp)
})
do.call("rbind",result)
#   id gender
# 1  1   Male
# 2  2 Female
# 4  3   Male
# 5  3 Female
# 6  4 Female
Автор: tobiasegli_te Размещён: 09.11.2017 12:29
Вопросы из категории :
32x32