R循环长数据返回最小值和累积值

Jim*_*Jim 2 loops r dataframe cumulative-sum

这是我的数据的链接.它看起来像这样:

year    cars    company
1975    11.75   chevy
1976    19.71   chevy
1977    21.23   chevy
1978    11.00   chevy
1979    8.26    chevy
1980    8.63    chevy
1981    19.09   chevy
1982    30.52   chevy
1983    27.51   chevy
Run Code Online (Sandbox Code Playgroud)

我想创建两个新的变量列:

  1. year_first,它将返回公司在数据中列出的第一年(例如,对于每个"chevy"行,这将是"1975")
  2. cars_cumulative,它将返回截至该点生产的特定公司的所有汽车的累计总数

因此,我希望我的数据看起来像这样:

year    cars    company year_first  cars_cumulative
1975    11.75   chevy   1975        11.75
1976    19.71   chevy   1975        31.46
1977    21.23   chevy   1975        52.69
1978    11.00   chevy   1975        63.69
1979    8.26    chevy   1975        71.95
1980    8.63    chevy   1975        80.58
1981    19.09   chevy   1975        99.67
1982    30.52   chevy   1975        130.19
1983    27.51   chevy   1975        157.70
Run Code Online (Sandbox Code Playgroud)

我想我应该写一个for循环?我只是不确定最好的方法.

lmo*_*lmo 6

以下基本R技术应该适用于data.frame df:

df <- data.frame(year=1975:1983, 
                 cars=c(11.75, 19.71, 21.23, 11, 8.26, 8.63, 19.09, 30.52, 27.51), 
                 company=rep("chevy", length(1975:1983)))
# add variables
df$year_first <- ave(df$year, df$company, FUN=min)
df$cars_cumulative <- ave(df$cars, df$company, FUN=cumsum)
Run Code Online (Sandbox Code Playgroud)

@rawr提到的一个很好的补充是,上面的这些行可以包装在within其中,告诉R使用data.frame作为第一个参考点:

within(df, {
  year_first <- ave(year, company, FUN=min)
  cars_cumulative <- ave(cars, company, FUN=cumsum)
})
Run Code Online (Sandbox Code Playgroud)

使用within不仅可以节省许多"df $"前缀的输入,这使代码更容易阅读,但它也可以帮助组织代码,因为您可以将所有其他变量的创建放在一个代码块中.

如果您正在使用非常大的数据集,或者您喜欢简洁的代码,那么您可以查看data.table:

library(data.table)
setDT(df)
df[, c("year_first", "cars_cumulative"):=list(min(year), cumsum(cars)), by="company"]
# or 
df[, `:=`(year_first = year[1L], cars_cumulative = cumsum(cars)), by=company]
Run Code Online (Sandbox Code Playgroud)

或者使用dplyr:

library(dplyr)
df2 = df %>% group_by(company) %>% 
  mutate(year_first = first(year), cars_cumulative = cumsum(cars))
Run Code Online (Sandbox Code Playgroud)