R / dplyr: суммировать данные, не группируя их

У меня есть такой фрейм данных:

ID V1 V2
A  2  June
B  3  May
A  2  January
F  4  December

Я хочу добавить V3, который дает мне количество записей по самому раннему V2 в каждом идентификаторе:

ID V1 V2        V3
A  2  June      January
B  3  May       May
A  2  January   January
F  4  December  December

Как я могу это сделать?


person questionmark    schedule 09.06.2020    source источник
comment
@s_t, V3 и V2 не совпадают в первой строке.   -  person 9314197    schedule 09.06.2020
comment
@questionmark, что здесь делает V1?   -  person 9314197    schedule 09.06.2020
comment
@ 9314197 ты прав, мне плохо.   -  person s__    schedule 09.06.2020


Ответы (2)


Если вы хотите получить самый ранний месяц V2 для каждого ID, возможно, вы можете сгруппировать его, а затем снова разгруппировать (см. Дополнительные комментарии в коде ниже):

# load packages
library(tidyverse)
library(lubridate)

# data
data <- read.table(header = TRUE, text = "
    ID V1 V2
    A  2  June
    B  3  May
    A  2  January
    F  4  December
")

# 1. group by ID
# 2. get the earliest month with parsing by 'lubridate' package
# 3. ungroup
# 4. make months to words with 'lubridate' again
data %>%
    group_by(ID) %>%
    mutate(V3 = min(month(parse_date_time(V2, "%m")))) %>%
    ungroup() %>%
    mutate(V3 = month(V3, label = TRUE, abbr = FALSE))
person Community    schedule 09.06.2020

Не совсем dplyr, но я считаю, что это довольно легко читать (по крайней мере, не так много вложенных скобок). Также: Моя функция minmonth удобна для повторного использования в другой раз и легко переводится для ввода на неанглийский язык:

dat <- read.table(text = "ID V1 V2
                           A  2  June
                           B  3  May
                           A  2  January
                           F  4  December", header = TRUE)

minmonth <- function(m){
  months <- c(January = 1, February = 2, March = 3,  # easily translated to 
             April = 4, May = 5, June = 6, July = 7, # other languages
             August = 8, September = 9, October = 10,
             November = 11, December = 12)
  m <- months[m]                                     # no static typing in R
  smallest <- min(m)
  return(names(months)[smallest])
}

dat$V3 <- ave(dat$V2, dat$ID, FUN = minmonth)
person Bernhard    schedule 09.06.2020