Как обеспечить результат, если присутствует хотя бы один элемент? - PullRequest
1 голос
/ 03 октября 2019

У меня есть следующий фрейм данных '

file<-c('510-1','510-1','510-2','510-2','510-4')
sev<-c('F','M','M','M','F')
df<-data.frame(file,sev)

Я хочу создать другую переменную с именем category. Если хотя бы у одного из file есть sev из F, я хочу, чтобы category был назван F, чтобы столбцу категории потребовалось следующее

   file sev category
1 510-1   F F
2 510-1   M F
3 510-2   M M
4 510-2   M M
5 510-4   F F 

Как мне это сделать?

Ответы [ 4 ]

2 голосов
/ 03 октября 2019

Опция с dplyr

library(dplyr)
df %>% 
    group_by(file) %>%
    mutate(category = c("M", "F")[sum(sev == "F") + 1])
# A tibble: 5 x 3
# Groups:   file [3]
#  file  sev   category
#  <fct> <fct> <chr>   
#1 510-1 F     F       
#2 510-1 M     F       
#3 510-2 M     M       
#4 510-2 M     M       
#5 510-4 F     F     

Или с использованием match

df %>% 
   group_by(file) %>%
   mutate(category = c("F", "M")[match("F", sev, nomatch = 2)])
2 голосов
/ 03 октября 2019

После группировки вы можете использовать функцию any в операторе if для создания нового столбца.

library(dplyr)

df %>% 
  group_by(file) %>% 
  mutate(category = if(any(sev == 'F')) 'F' else 'M')

# # A tibble: 5 x 3
# # Groups:   file [3]
#   file  sev   category
#   <fct> <fct> <chr>   
# 1 510-1 F     F       
# 2 510-1 M     F       
# 3 510-2 M     M       
# 4 510-2 M     M       
# 5 510-4 F     F      

Или с таблицей данных (тот же вывод)

library(data.table)
setDT(df)

df[, category := if(any(sev == 'F')) 'F' else 'M', by = file]
1 голос
/ 03 октября 2019

ave кажется простой базой R для выполнения того, о чем спрашивает вопрос. Если хотя бы (any) один sev == 'F', то индекс для подстановки потенциального вектора результатов c('M', 'F') равен 2.

df$category <- ave(df$sev, df$file, FUN = function(x) c('M', 'F')[1+any(x == 'F')])
df
#   file sev category
#1 510-1   F        F
#2 510-1   M        F
#3 510-2   M        M
#4 510-2   M        M
#5 510-4   F        F
0 голосов
/ 03 октября 2019

Если вы в порядке с file и sev, не являющимися факторами, это работает и невероятно быстро.

file<-c('510-1','510-1','510-2','510-2','510-4')
sev<-c('F','M','M','M','F')
df<-data.frame(file, sev, stringsAsFactors = F)
lookup = sapply(unique(df$file), FUN = function(f) ifelse(any(df[file == f, 'sev'] == 'F'), 'F', 'M'))
df$category = lookup[df$file]
df
#>    file sev category
#> 1 510-1   F        F
#> 2 510-1   M        F
#> 3 510-2   M        M
#> 4 510-2   M        M
#> 5 510-4   F        F

Создано в 2019-10-03 представьте пакет (v0.3.0)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...