累积金额和数据组织

时间:2014-08-02 19:50:13

标签: r csv merge cumulative-sum

我有大约40000个来自不同样本的降雨数据值,这些数据会不断更新。 csv文件的组织方式如下:

NAME;       YEAR;   ID;     VALUE
Sample1;    1998;   354;    45
Sample1;    1999;   354;    23
Sample1;    2000;   354;    66
Sample1;    2001;   354;    98
Sample1;    2002;   354;    36
Sample1;    2003;   354;    59
Sample1;    2004;   354;    64
Sample1;    2005;   354;    23
Sample1;    2006;   354;    69
Sample1;    2007;   354;    94
Sample1;    2008;   354;    24
Sample2;    1964;   1342;    7
Sample2;    1965;   1342;   24
Sample3;    2002;   859;    90
Sample3;    2003;   859;    93
Sample3;    2004;   859;    53
Sample3;    2005;   859;    98 

我想对R脚本做什么如下:为一组样本创建一个新行(例如,对于所有Sample1,然后从所有Sample2的值重新开始,然后从值重新开始)对于所有Sample3等等,根据之前的值(降雨量数据的累积总和)求和,例如样本1的结果就像这个例子中的CUM_RAINFALL一样(对于第一个例子,这样的事情:CUM_RAINFALL 1和那么45 + 23,然后是68 + 66,然后是134 + 232,依此类推,直到Sample1结束,Sample2的值应该接管,程序应该重新开始)

NAME;       YEAR;   ID;     VALUE    CUM_RAINFALL
Sample1;    1998;   354;    45;       45
Sample1;    1999;   354;    23;       68
Sample1;    2000;   354;    66;      134
Sample1;    2001;   354;    98;      232
Sample1;    2002;   354;    36;      268
Sample1;    2003;   354;    59;      327
Sample1;    2004;   354;    64;      391
Sample1;    2005;   354;    23;      414
Sample1;    2006;   354;    69;      483
Sample1;    2007;   354;    94;      577
Sample1;    2008;   354;    24;      601
Sample2;    1964;   1342;    7;      7
Sample2;    1965;   1342;   24;      31
Sample3;    2002;   859;    90;      90
Sample3;    2003;   859;    93;      183
Sample3;    2004;   859;    53;      236
Sample3;    2005;   859;    98;      334

由此我想写一个新文件,其中包含超过3个值的所有行(在给定示例中,Sample2不会写入文件,因为它只包含2个值)

在R中有一种简单的方法吗?任何帮助表示赞赏!在以下链接中,您将找到包含数据的csv:https://dl.dropboxusercontent.com/u/16277659/sample.cs

3 个答案:

答案 0 :(得分:2)

以下是使用data.table包的解决方案,假设您的数据存储在dat中:

require(data.table)
ans = setDT(dat)[, crain := cumsum(VALUE[.N > 3L]), by=NAME][!is.na(crain)]
  • setDT将data.frame转换为data.table
  • 然后,我们按NAME进行分组,并针对每个唯一群组计算该群组的VALUE的累积总和,如果该群组的观察数量( = .N,内置特殊变量)是> 3L。我们通过引用将值分配给新列crain
  • 由于我们没有为具有< = 3L观察值的组计算cumsum,因此它们中将包含NA个值。我们利用它来分组所需的结果。

现在,您可以在write.table(.)上使用ans,如其他答案所示。

注意:此答案假定您的数据集当然不包含NA列的VALUE值。

答案 1 :(得分:0)

基础R中的40k观测值应该没问题。

d$CUMRAIN <- unlist(by(d$VALUE, d$NAME, cumsum), use.names = FALSE)
d
#       NAME YEAR   ID VALUE CUMRAIN
# 1  Sample1 1998  354    45      45
# 2  Sample1 1999  354    23      68
# 3  Sample1 2000  354    66     134
# 4  Sample1 2001  354    98     232
# 5  Sample1 2002  354    36     268
# 6  Sample1 2003  354    59     327
# 7  Sample1 2004  354    64     391
# 8  Sample1 2005  354    23     414
# 9  Sample1 2006  354    69     483
# 10 Sample1 2007  354    94     577
# 11 Sample1 2008  354    24     601
# 12 Sample2 1964 1342     7       7
# 13 Sample2 1965 1342    24      31
# 14 Sample3 2002  859    90      90
# 15 Sample3 2003  859    93     183
# 16 Sample3 2004  859    53     236
# 17 Sample3 2005  859    98     334

我在这里使用by,但这里有一些其他方法可以按因子级别计算cumsum

mapply(cumsum, with(d, split(VALUE, NAME)))
sapply(unname(split(d$VALUE, d$NAME)), cumsum)
unsplit(sapply(split(d$VALUE, d$NAME), cumsum), d$NAME) 

后者可能是最有利的,因为它会降低因子名称。

还有

library(plyr)
ddply(d, .(NAME), mutate, CUMSUM = cumsum(VALUE))     

要为三个以上的观察提供子集,您可以使用简单的table

t <- table(d$NAME)
ss <- d[d$NAME %in% names(t)[t > 3], ]

然后用

将其写入文件
write.table(ss, "filename", sep = ";")

答案 2 :(得分:0)

这是使用dplyr

的另一种方法
library(dplyr)

data %>%                                   # your data frame
  group_by(NAME) %>%                       # the grouping variable. could add more variables if necessary
  filter(n() > 3) %>%                      # n()  calculates the number of rows per group and then only those with more than 3 are filtered (selected)
  mutate(CUMRAIN = cumsum(VALUE)) %>%      # add a new column "CUMRAIN"
  write.table(., "test.csv", sep = ";")    # write the subset to a file. The "." indicates that it uses the output of the previous operations piped by %>%   

操作是&#34;管道&#34;一起使用%>%运算符。

更新:如@ Arun的回答所述,没有必要计算少于3次观测的样本的累积降雨量,因此我们可以先使用过滤操作(在变异之前)制作包含3个以上观测值的所有样本的子集,然后计算累积降雨量。