字符串和子集后面的多个循环

时间:2013-12-06 12:00:13

标签: r

我目前仍然坚持我的数据框,我想知道如何做“子集子集的子集” 这是我数据框的一部分:

    YEAR    RN      DATE    NAME            SITE           LONG SP                         SUMNB            NB100
1   2011    RNN027  15056   ESTAGNOL    RNN027-Estagnol 02  310 Anthocharis cardamines (Linnaeus, 1758) 1   0.3225806
2   2011    RNN027  15075   ESTAGNOL    RNN027-Estagnol 02  310 Anthocharis cardamines (Linnaeus, 1758) 1   0.3225806
3   2003    RNN027  12166   ESTAGNOL    RNN027-Estagnol 03  330 Anthocharis cardamines (Linnaeus, 1758) 2   0.6060606
4   2006    RNN027  13252   ESTAGNOL    RNN027-Estagnol 03  330 Anthocharis cardamines (Linnaeus, 1758) 2   0.6060606
5   2006    RNN027  13257   ESTAGNOL    RNN027-Estagnol 03  330 Anthocharis cardamines (Linnaeus, 1758) 2   0.6060606
6   2005    RNN027  12895   ESTAGNOL    RNN027-Estagnol 01  540 Anthocharis cardamines (Linnaeus, 1758) 2   0.3703704

我的观点是计算每个物种的丰度因子。要做到这一点,我必须隔离每个物种,每年和每个地点的每个计数日期。

我的第一个想法是做多个循环并按照先前的标准对每个步骤进行子步骤:

DF - >循环站点;每个站点的子集 - >循环YEAR;每个YEAR的子集 - >循环SP;每种物种的子集 - >观察日期

隔离这些日期需要进一步修改(添加行),但我需要能够在之后重写修改后的子集并重建新的数据帧。

我构建了我的循环命令:

LOOPSITE<-sort(unique(DF$SITE))
for(i in LOOPSITE){
  print(i)
  LOOPSITESUB<-subset(DF,grepl(i,SITE))
  LOOPYEAR<-sort(unique(LOOPSITESUB$YEAR))
  print(LOOPYEAR)

  for(j in LOOPYEAR){
    print(j)
    LOOPYEARSUB<-subset(LOOPSITESUB,grepl(j,YEAR))
    LOOPSP<-sort(unique(LOOPYEARSUB$SP))
    print(length(LOOPSP))
       for(k in LOOPSP){
         print(k)
         LOOPSPSUB<-subset(LOOPYEARSUB,grepl(k,SP))
         print(sum(LOOPYEARSUB$SUMNB))
         print(head(LOOPSPSUB))
    }      
  }
}

我能够遵循我的脚本正在使用所有这些“打印”命令,并且它一直在工作,直到我到达物种subseting。由于未知原因,最后一个子集并不涉及每个物种,而只涉及其中的一些。以下是最后一个SITE和上一年的输出的一部分:

"RNN027-Estagnol 01"
...(I skipped all the sites)
"RNN027-Estagnol 06"
"2003"
...(I skipped all the years)
"2011"
[1] 22
[1] "Aricia agestis D., 1775"
[1] 107
   YEAR     RN       DATE      NOM               SITE LONG                      SP SUMNB     NB100
66 2011 RNN027 2011-04-21 ESTAGNOL RNN027-Estagnol 06  260 Aricia agestis D., 1775         1 0.3846154
67 2011 RNN027 2011-05-22 ESTAGNOL RNN027-Estagnol 06  260 Aricia agestis D., 1775     1 0.3846154
68 2011 RNN027 2011-08-05 ESTAGNOL RNN027-Estagnol 06  260 Aricia agestis D., 1775     2 0.7692308
[1] "Brintesia circe (Fabricius, 1775)"
[1] 107
[1] YEAR  RN    DATE  NOM   SITE  LONG  SP    SUMNB NB100
<0 rows> (or 0-length row.names)
[1] "Carcharodus alceae (Esper, 1780)"
[1] 107
[1] YEAR  RN    DATE  NOM   SITE  LONG  SP    SUMNB NB100
<0 rows> (or 0-length row.names)

它适用于“Aricia agestis D.,1775”,但不适用于“Brintesia circe(Fabricius,1775)”。 我在我的数据框架上验证了,在这个时间和地点已经观察到第二个物种,并且具有与前一个相同的格式......它应该有效。

我可以像这样堆叠多少个循环?还有另一种方法吗? (它会方便快捷)。我知道“拆分”功能,他基本上解散了每个群体,但由于我无法利用每一个“块”,它不适合我的任务。我可能错了。

在最后一步(修改所有子集之后),我应该能够在新数据帧中编写每个子集来重建我输入的修改版本。

我可能是我可能会走的最糟糕的方式! 如果需要,我可以提供进一步的解释!

感谢您的帮助!

编辑:

我会试着解释一下我想做什么。 为了计算我的丰度指数,我需要在观察的每个时间“会话”之前和之后添加“空白”行。基本上,我试图获得3个不同因素(SITE,YEAR和SP)的每个组合的子集。

以下是我想要获得的输出类型的示例。  对于每个SITE X / YEAR Y / SP Z可能的组合:

 YEAR    RN      DATE    NAME            SITE           LONG SP  SUMNB NB100
----ADD A NEW ROW----DATE MINUS 7 DAYS-----------------------------------------------------------------------------------
1   Y    RNN027  15056   ESTAGNOL    RNN027-Estagnol X  310 SP Z  1   0.3225806
2   Y    RNN027  15075   ESTAGNOL    RNN027-Estagnol X  310 SP Z  1   0.3225806
3   Y    RNN027  12166   ESTAGNOL    RNN027-Estagnol X  330 SP Z  2   0.6060606
4   Y    RNN027  13252   ESTAGNOL    RNN027-Estagnol X  330 SP Z  2   0.6060606
5   Y    RNN027  13257   ESTAGNOL    RNN027-Estagnol X  330 SP Z  2   0.6060606
6   Y    RNN027  12895   ESTAGNOL    RNN027-Estagnol X  540 SP Z  2   0.3703704
----ADD A NEW ROW----DATE PLUS 7 DAYS-----------------------------------------------------------------------------------

然后我重写并编译新DF中的每个修改后的子集。

编辑2: 使用“拆分(DF,列表(DF $ SITE,DF $ YEAR,DF $ SP))”使我的计算机崩溃,除非我删除了未使用的值。我得到了我想要的,但我如何访问和修改每个子集?

2 个答案:

答案 0 :(得分:3)

我想你正在寻找aggregate

aggregate(SUMNB ~ SITE + YEAR + SP, DF, sum)

#                 SITE YEAR                                      SP SUMNB
# 1 RNN027-Estagnol 03 2003 Anthocharis cardamines (Linnaeus, 1758)     2
# 2 RNN027-Estagnol 01 2005 Anthocharis cardamines (Linnaeus, 1758)     2
# 3 RNN027-Estagnol 03 2006 Anthocharis cardamines (Linnaeus, 1758)     4
# 4 RNN027-Estagnol 02 2011 Anthocharis cardamines (Linnaeus, 1758)     2

该命令为SUMNBSITEYEAR的每个组合计算SP中所有值的总和。


修改

以下代码是否会产生您想要的内容?

do.call(rbind, by(DF, DF[c("SITE", "YEAR", "SP")], FUN = function(x) {
  tmp <- x[c(1, seq(nrow(x)), nrow(x)), ]
  tmp$DATE[1] < tmp$DATE[1] - 7
  tmp$DATE[nrow(tmp)] <- tmp$DATE[nrow(tmp)] + 7
  return(tmp)
}))

答案 1 :(得分:1)

根据您的修改,我认为这可能很有用:

set.seed(11)
DF <- data.frame(YEAR = sample(c(2001, 2003), 5, T),     #random data
                 SITE = sample(c("a", "b"), 5, T),
                 SP = sample(c("sp1", "sp2"), 5, T),
                 DATE = sample(12345:15678, 5))

res <- lapply(split(DF, list(DF$SITE, DF$YEAR, DF$SP)), 
                function(x) 
                {
                 if(nrow(x) > 0)
                  {
                   row1 <- x[1,]
                   names(row1) <- colnames(x)
                   row1["DATE"] <- x$DATE[1] - 7

                   rown <- x[nrow(x),]
                   names(rown) <- colnames(x)
                   rown["DATE"] <- x$DATE[nrow(x)] + 7

                   rbind(row1, x, rown)
                  } 
                })
DF2 <- do.call(rbind, res)
rownames(DF2) = seq_len(nrow(DF2))

DF
#  YEAR SITE  SP  DATE
#1 2001    b sp1 14257
#2 2001    a sp1 13950
#3 2003    a sp2 13446
#4 2001    b sp2 12870
#5 2001    a sp2 13943
DF2
#   YEAR SITE  SP  DATE
#1  2001    a sp1 13943
#2  2001    a sp1 13950
#3  2001    a sp1 13957
#4  2001    b sp1 14250
#5  2001    b sp1 14257
#6  2001    b sp1 14264
#7  2001    a sp2 13936
#8  2001    a sp2 13943
#9  2001    a sp2 13950
#10 2001    b sp2 12863
#11 2001    b sp2 12870
#12 2001    b sp2 12877
#13 2003    a sp2 13439
#14 2003    a sp2 13446
#15 2003    a sp2 13453