我有大约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
答案 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
。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个以上观测值的所有样本的子集,然后计算累积降雨量。