#r #aggregate
#r #aggregate
Вопрос:
У меня есть набор данных, который включает все продажи для компании за данный год (код компании = gvkey, год = fyeqarq, продажи = saley). Я пытаюсь рассчитать возраст компании, используя последний год, в котором указаны ее продажи, и вычитая его из первого года, в котором указаны продажи.
При этом я продолжаю сталкиваться с различными проблемами или ошибками. Из-за текущего RStudio полностью перестает работать. Возможно, кто-нибудь мог бы указать, есть ли лучший способ его кодирования? Или, если это неправильно? Я довольно новичок в R.
Я также пытался использовать dplyrs «first» и «last», но, думаю, я применил его неправильно.
age <- function(x){
out <- c(NA, x[seq_len(max(df_age$fyearq))]-x[seq_len(min(df_age$fyearq))])
return(out) }
df_age$companyage <- do.call("c", by(df_age$fyearq, df_age$gvkey, age))
Выборка из набора данных (первые 100 строк) с использованием dput:
structure(list(gvkey = c(1000L, 1000L, 1000L, 1000L, 1000L, 1000L,
1000L, 1000L, 1000L, 1000L, 1001L, 1001L, 1001L, 1001L, 1003L,
1003L, 1003L, 1003L, 1003L, 1003L, 1003L, 1003L, 1004L, 1004L,
1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L,
1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L,
1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L,
1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L,
1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L, 1004L,
1004L, 1004L, 1004L, 1004L, 1005L, 1005L, 1005L, 1005L, 1005L,
1006L, 1006L, 1007L, 1007L, 1007L, 1007L, 1007L, 1008L, 1008L,
1008L, 1008L, 1009L, 1009L, 1009L, 1009L, 1009L, 1009L, 1009L,
1009L, 1009L, 1009L, 1009L), fyearq = c(1969L, 1970L, 1971L,
1972L, 1973L, 1974L, 1975L, 1976L, 1977L, 1978L, 1983L, 1984L,
1985L, 1986L, 1983L, 1984L, 1985L, 1986L, 1987L, 1988L, 1989L,
1990L, 1968L, 1969L, 1970L, 1971L, 1972L, 1973L, 1974L, 1975L,
1976L, 1977L, 1978L, 1979L, 1980L, 1981L, 1982L, 1983L, 1984L,
1985L, 1986L, 1987L, 1988L, 1989L, 1990L, 1991L, 1992L, 1993L,
1994L, 1995L, 1996L, 1997L, 1998L, 1999L, 2000L, 2001L, 2002L,
2003L, 2004L, 2005L, 2006L, 2007L, 2008L, 2009L, 2010L, 2011L,
2012L, 2013L, 2014L, 2015L, 2016L, 2017L, 2018L, 1978L, 1979L,
1980L, 1981L, 1982L, 1982L, 1983L, 1982L, 1983L, 1984L, 1985L,
1986L, 1983L, 1984L, 1985L, 1986L, 1983L, 1984L, 1985L, 1986L,
1987L, 1988L, 1989L, 1990L, 1991L, 1992L, 1993L), saley = c(7.095,
9.478, 7.983, 8.201, 8.467, 9.961, 11.295, 16.226, 18.014, 18.92,
4.921, 6.434, 7.865, 13.997, 2.647, 2.419, 2.761, 7.392, 8.852,
79.894, 48.393, 19.502, 1.694, 4.166, 5.063, 5.185, 7.555, 11.174,
13, 13.979, 18.381, 20.496, 28.669, 32.563, 30.454, 41.766, 40.465,
40.475, 52.723, 53.836, 66.376, 74.543, 90.007, 108.635, 116.092,
107.339, 98.072, 98.306, 97.191, 1212.356, 1422.924, 1863.645,
2582.936, 2596.419, 2222.306, 1680.935, 1522.926, 1572.618, 1789.764,
2133.438, 2541.417, 3300.719, 3549.624, 3260.308, 4386.042, 5029.107,
5364.4, 4400.8, 3966.3, 4134.1, 3869, 4239.5, 1425.9, 1.293,
2.583, 3.762, 6.872, 7.231, 2.287, 2.289, 1.724, 1.334, 1.009,
1.064, 1.204, 0.065, 0.469, 0.08, 1.022, 3.565, 4.436, 4.939,
5.013, 4.508, 4.581, 8.058, 8.16, 8.373, 9.362, 169.922)), row.names = c(6735L,
8891L, 11367L, 14026L, 16823L, 19660L, 22506L, 25386L, 28253L,
31209L, 50854L, 57451L, 64185L, 71149L, 50855L, 57452L, 64186L,
71150L, 78490L, 85850L, 93149L, 100335L, 4810L, 6736L, 8892L,
11368L, 14027L, 16824L, 19661L, 22507L, 25387L, 28254L, 31210L,
34111L, 36988L, 39814L, 44656L, 50856L, 57453L, 64187L, 71151L,
78491L, 85851L, 93150L, 100336L, 107454L, 114551L, 121923L, 129787L,
138848L, 149183L, 159747L, 170254L, 181110L, 191976L, 202480L,
212402L, 221703L, 230643L, 239235L, 247644L, 255712L, 263449L,
270929L, 278189L, 285331L, 292379L, 299553L, 306708L, 313762L,
320630L, 327242L, 333472L, 31211L, 34112L, 36989L, 39815L, 44657L,
44658L, 50857L, 44659L, 50858L, 57454L, 64188L, 71152L, 50859L,
57455L, 64189L, 71153L, 50860L, 57456L, 64190L, 71154L, 78492L,
85852L, 93151L, 100337L, 107455L, 114552L, 121924L), class = "data.frame")
Ответ №1:
Вы можете использовать tapply
для вычисления diff
коэффициента range
переменной fyearq
of для каждой компании
tapply(df_age$fyearq, df_age$gvkey, function(x) diff(range(x)))
#1000 1001 1003 1004 1005 1006 1007 1008 1009
# 9 3 7 50 4 1 4 3 10
Или попробуйте aggregate
aggregate(fyearq ~ gvkey, df_age, FUN = function(x) diff(range(x)))
# gvkey fyearq
#1 1000 9
#2 1001 3
#3 1003 7
#4 1004 50
#5 1005 4
#6 1006 1
#7 1007 4
#8 1008 3
#9 1009 10
Ответ №2:
Я бы также выбрал подход dplyr, поэтому прокомментируйте, что могло быть не так, когда вы его попробовали.
Проблема с first
and last
заключается в том, что они принимают первое и последнее значения в массиве независимо от их значений. Так, например
example <- c(10, 0, 999, -1)
> first(example)
[1] 10
> last(example)
[1] -1
Для вашей проблемы вам действительно нужны значения min
и max
массива:
> min(example)
[1] -1
> max(example)
[1] 999
Нет, перейдем к интересующему вас случаю (я назвал данные, которые вы предоставили df
):
df %>%
group_by(gvkey) %>%
summarize(age = max(fyearq) - min(fyearq))
# A tibble: 9 x 2
gvkey age
<int> <dbl>
1 1000 9
2 1001 3
3 1003 7
4 1004 50
5 1005 4
6 1006 1
7 1007 4
8 1008 3
9 1009 10
То, что мы сделали, было сначала сгруппировано по идентификатору каждой компании, поэтому минимальные и максимальные значения будут рассчитываться внутри каждой компании. Затем мы суммировали, вычитая минимальный год из максимального года.
Кроме того, вы можете использовать mutate
для добавления возрастов в фрейм данных в качестве нового столбца:
df %>%
group_by(gvkey) %>%
mutate(age = max(fyearq) - min(fyearq)) %>%
ungroup()
# A tibble: 100 x 4
gvkey fyearq saley age
<int> <int> <dbl> <dbl>
1 1000 1969 7.10 9
2 1000 1970 9.48 9
3 1000 1971 7.98 9
4 1000 1972 8.20 9
5 1000 1973 8.47 9
6 1000 1974 9.96 9
7 1000 1975 11.3 9
8 1000 1976 16.2 9
9 1000 1977 18.0 9
10 1000 1978 18.9 9
# ... with 90 more rows
Редактировать: для краткого ознакомления с логикой dplyr и некоторыми из ее наиболее полезных функций эта глава R for Data Science действительно хороша, и ее содержание имеет большое значение.