Как вставить значения между двумя фреймами данных при соблюдении условий - PullRequest
2 голосов
/ 05 апреля 2019

У меня большой фрейм данных (my_DF) с 4 важными столбцами: ID (1 -> 100), ГОД (2000, 2001, 2002, 2003, 2004, 2005), МЕСЯЦ (январь -> декабрь), ДЛИНА(непрерывные значения от 0,1 до 1,0).Что-то вроде:

        YEAR      MONTH       ID   LENGHT 
1       2000     january      S1   0.2 
2       2000     january      S1   0.3
3       2000     january      S1   0.1 
4       2000     january      S2   0.5
5       2000     january      S2   0.3 
6       2000     february     S1   0.9
7       2000     february     S1   0.4 
8       2000     february     S1   0.6 
9       2000     february     S3   0.4
10      2000     february     S3   0.3 
11      2000     march        S1   0.7 
...

Мне нужно добавить новый столбец в фрейм данных, заполненный средней длиной для каждой уникальной ситуации, поэтому для каждого значения ID, YEAR и MONTH.

Мне удалось получить значения, которые я искал, благодаря агрегату:

agg <- aggregate(my_DF["LENGHT"], by = list(my_DF$YEAR, my_DF$MONTH, my_DF$ID), median)

Таким образом, я получаю значения, которые хотел, но, конечно, это просто создает новый фрейм данных.Мне не удается найти быстрый способ вставить значения фрейма данных «agg» в новый столбец фрейма данных «my_DF», основываясь на сопоставлении YEAR, MONTH и ID.

Например, я хочуполучить что-то вроде:

        YEAR     MONTH       ID   LENGHT   MONTHLY_LENGHT_MEDIAN
1       2000     january      S1   0.2           0.2
2       2000     january      S1   0.3           0.2
3       2000     january      S1   0.1           0.2
4       2000     january      S2   0.5           0.4
5       2000     january      S2   0.3           0.4
6       2000     february     S1   0.9           0.6
7       2000     february     S1   0.4           0.6
8       2000     february     S1   0.6           0.6
9       2000     february     S3   0.4           0.35
10      2000     february     S3   0.3           0.35
11      2000     march        S1   0.7           0.7

Итак, мне интересно, подходит ли условная команда в моем случае (если ifelse ...).
К сожалению, я не очень хорошо с этимиКоманды ... Как я мог сделать?Спасибо за помощь!

Ответы [ 2 ]

2 голосов
/ 05 апреля 2019

Вместо суммирования с aggregate и затем merge, непосредственно используйте ave из base R, чтобы создать столбец

my_df$MONTHLY_LENGHT_MEDIAN <- with(my_df, ave(LENGHT, YEAR,
                  MONTH, ID, FUN = median))
mydf$MONTHLY_LENGHT_MEDIAN
#[1] 0.20 0.20 0.20 0.40 0.40 0.60 0.60 0.60 0.35 0.35

или с tidyverse

library(tidyverse)
my_df %>%
      group_by(LENGHT, YEAR, MONTH) %>%
      mutate(MONTHLY_LENGHT_MEDIAN = median(LENGHT))

данные

my_df <- structure(list(YEAR = c(2000L, 2000L, 2000L, 2000L, 2000L, 2000L, 
2000L, 2000L, 2000L, 2000L), MONTH = c("january", "january", 
"january", "january", "january", "february", "february", "february", 
"february", "february"), ID = c("S1", "S1", "S1", "S2", "S2", 
"S1", "S1", "S1", "S3", "S3"), LENGHT = c(0.2, 0.3, 0.1, 0.5, 
0.3, 0.9, 0.4, 0.6, 0.4, 0.3)), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10"))
1 голос
/ 05 апреля 2019

Вы можете просто сделать это в одну строку, используя data.table

library(data.table)
setDT(dt)[ , median := median(LENGHT), by = .(YEAR,MONTH,ID)]

> dt
    YEAR    MONTH ID LENGHT mean median
 1: 2000  january S1    0.2 0.20   0.20
 2: 2000  january S1    0.3 0.20   0.20
 3: 2000  january S1    0.1 0.20   0.20
 4: 2000  january S2    0.5 0.40   0.40
 5: 2000  january S2    0.3 0.40   0.40
 6: 2000 february S1    0.9 0.60   0.60
 7: 2000 february S1    0.4 0.60   0.60
 8: 2000 february S1    0.6 0.60   0.60
 9: 2000 february S3    0.4 0.35   0.35
10: 2000 february S3    0.3 0.35   0.35
...