使用for循环计算树增长

时间:2014-11-18 16:57:16

标签: r

我试图在一个数据框中计算一组树的直径增长,其中每一行在给定年份中是给定的树。通常,这类数据将每个单独的词干作为单行,每个词的直径在每个单独的列中给出,但由于各种原因,此数据框需要保持为每行在单个年份中的单个词干。数据的简化模型版本如下

df<-data.frame("Stem"=c(1:5,1:5,1,2,3,5,1,2,3,5,6),
           "Year"=c(rep(1997,5), rep(1998,5), rep(1999,4), rep(2000,5)),
           "Diameter"=c(1:5,seq(1.5,5.5,1),2,3,4,6,3,5,7,9,15))
df
   Stem Year  DAP
1     1 1997  1.0
2     2 1997  2.0
3     3 1997  3.0
4     4 1997  4.0
5     5 1997  5.0
6     1 1998  1.5
7     2 1998  2.5
8     3 1998  3.5
9     4 1998  4.5
10    5 1998  5.5
11    1 1999  2.0
12    2 1999  3.0
13    3 1999  4.0
14    5 1999  6.0
15    1 2000  3.0
16    2 2000  5.0
17    3 2000  7.0
18    5 2000  9.0
19    6 2000 15.0

我想要完成的是制作一个新的列,它在给定的年份中获取给定茎的直径,并减去前一年同一茎的直径。我假设这将需要一些嵌套的for循环。像

这样的东西
for (i in 1:length(unique(df$Stem_ID){
  for (t in 2:length(unique(df$Year){
.....
  }
}

我正在努力的是如何编写计算的函数: 每个茎的直径[t] - 直径[t-1]。任何建议都将不胜感激。

2 个答案:

答案 0 :(得分:0)

尝试:

> do.call(rbind, lapply(split(df, df$Stem), function(x) transform(x, diff = c(0,diff(x$Diameter)))))
     Stem Year Diameter diff
1.1     1 1997      1.0  0.0
1.6     1 1998      1.5  0.5
1.11    1 1999      2.0  0.5
1.15    1 2000      3.0  1.0
2.2     2 1997      2.0  0.0
2.7     2 1998      2.5  0.5
2.12    2 1999      3.0  0.5
2.16    2 2000      5.0  2.0
3.3     3 1997      3.0  0.0
3.8     3 1998      3.5  0.5
3.13    3 1999      4.0  0.5
3.17    3 2000      7.0  3.0
4.4     4 1997      4.0  0.0
4.9     4 1998      4.5  0.5
5.5     5 1997      5.0  0.0
5.10    5 1998      5.5  0.5
5.14    5 1999      6.0  0.5
5.18    5 2000      9.0  3.0
6       6 2000     15.0  0.0

答案 1 :(得分:0)

Rnso的回答有效。你也可以稍微缩短一下:

>df[order(df$Stem),]
>df$diff <- unlist(tapply(df$Diameter,df$Stem, function(x) c(NA,diff(x))))

   Stem Year Diameter diff
1     1 1997      1.0   NA
6     1 1998      1.5  0.5
11    1 1999      2.0  0.5
15    1 2000      3.0  1.0
2     2 1997      2.0   NA
7     2 1998      2.5  0.5
12    2 1999      3.0  0.5
16    2 2000      5.0  2.0
3     3 1997      3.0   NA
8     3 1998      3.5  0.5
13    3 1999      4.0  0.5
17    3 2000      7.0  3.0
4     4 1997      4.0   NA
9     4 1998      4.5  0.5
5     5 1997      5.0   NA
10    5 1998      5.5  0.5
14    5 1999      6.0  0.5
18    5 2000      9.0  3.0
19    6 2000     15.0   NA

或者,如果您愿意使用data.table包,您可以非常简洁:

>require(data.table)
>DT <- data.table(df)
>setkey(DT,Stem)
>DT <- DT[,diff:= c(NA, diff(Diameter)), by = Stem]
>df <- as.data.frame(DT)

   Stem Year Diameter diff
1     1 1997      1.0   NA
2     1 1998      1.5  0.5
3     1 1999      2.0  0.5
4     1 2000      3.0  1.0
5     2 1997      2.0   NA
6     2 1998      2.5  0.5
7     2 1999      3.0  0.5
8     2 2000      5.0  2.0
9     3 1997      3.0   NA
10    3 1998      3.5  0.5
11    3 1999      4.0  0.5
12    3 2000      7.0  3.0
13    4 1997      4.0   NA
14    4 1998      4.5  0.5
15    5 1997      5.0   NA
16    5 1998      5.5  0.5
17    5 1999      6.0  0.5
18    5 2000      9.0  3.0
19    6 2000     15.0   NA

如果你有一个大型数据集,data.table具有极快的优势。