【问题标题】:do.call and multiple function (x)do.call 和多功能 (x)
【发布时间】:2013-12-11 13:31:13
【问题描述】:

我目前正在尝试计算物种丰度指数,但我对 do.call 命令有点卡住了。

我有一个像这样构建的 DF:

    YEAR    RN      DATE    NOM         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
7   2005    RNN027  12910   ESTAGNOL    RNN027-Estagnol 01  540 Anthocharis cardamines (Linnaeus, 1758) 2   0.3703704

为了计算我的索引,我必须隔离每个 SITE/YEAR 组合并取第一个和最后一个日期来编辑它们(减去和加上 7 天)。

我应该可以使用以下命令来做到这一点(因为完成而无法正常工作):

do.call(rbind, by(DF, DF[c("YEAR","SITE")], FUN = function(x) {
  tmp <- x[c(1, nrow(x)), ]
  tmpmin<-min(tmp$DATE)
  tmpmax<-max(tmp$DATE)
  tmp1<-tmp1-7
  tmp2<-tmp2+7
  return(tmp)

但我不知道如何完成我的命令以适合我想要的:我需要保留修改后的日期,并在 SITE/YEAR/SP 的每个组合之前和之后分别添加它们。关键是检测每个站点的所有物种总和的第一个和最后一个观察日期,根据需要修改它们,并将它们添加到我得到的每个物种的时间重新分区中(每个“块”中的两个新行)。

我可以使用 SP 标准在每个“块”之前和之后添加一行,并使用以下代码(但该行是基于现在的第一个和最后一个日期,而不是我想要的日期):

do.call(rbind, by(DF, DF[c("YEAR","SITE", "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)
}))

我的问题是,如何链接这两个命令以成功地将包含我的第一个命令 (SITE/YEAR) 的日期的行添加到第二个命令 (SITE/YEAR/SP)。我尝试在我的 function(x) 命令以及另一个 do.call 命令中添加一个循环,但它不起作用。

编辑:

@Troy:昨天,我成功地在我的 do.call 命令中添加了一个循环:我的目标是对每个 SITE/YEAR 组合进行子集化,而不考虑物种。在每个子集中,我将我的时间分布的两个限制作为物种总和(因为我没有那个信息)。然后我用我在子集中收集的信息为每个物种写一行。 我的循环在这里为我写了一个包含 N 行的新数据框,用于 N 种具有最小和最大日期(见下文)。我将进一步将这个虚拟数据框与我的实际 DF 合并。

MIN<-data.frame(matrix(NA, nrow = 100, ncol = 9))
colnames(MIN)<-c("YEAR","RN","DATE","NOM","SITE","LONG","SP","SUMNB","NB100" )
MAX<-data.frame(matrix(NA, nrow = 100, ncol = 9))
colnames(MAX)<-c("YEAR","RN","DATE","NOM","SITE","LONG","SP","SUMNB","NB100" )
head(do.call(rbind, by(AGG100, AGG100[c("YEAR","SITE")], FUN = function(x) {

  splist<-unique(x$SP)
  lsp<-length(splist)
  for (i in 1:lsp){
  MIN$SP[i]<-as.character(splist[i])
  MIN$SITE[i]<-as.character(unique(x$SITE))
  MIN$DATE[i]<-as.character(min(x$DATE) - 7)
  MIN$RN[i]<-as.character(unique(x$RN))
  MIN$YEAR[i]<-as.character(unique(x$YEAR))
  MIN$NOM[i]<-as.character(unique(x$NOM))
  MIN$LONG[i]<-as.numeric(unique(x$LONG))
  MIN$SUMNB[i]<-0
  MIN$NB100[i]<-0
  MAX$SP[i]<-as.character(splist[i])
  MAX$SITE[i]<-as.character(unique(x$SITE))
  MAX$DATE[i]<-as.character(min(x$DATE) + 7)
  MAX$RN[i]<-as.character(unique(x$RN))
  MAX$YEAR[i]<-as.character(unique(x$YEAR))
  MAX$NOM[i]<-as.character(unique(x$NOM))
  MAX$LONG[i]<-as.numeric(unique(x$LONG))
  MAX$SUMNB[i]<-0
  MAX$NB100[i]<-0

MINMAX<- rbind(MIN,MAX)
MINMAX<-MINMAX[complete.cases(MINMAX),]  

}
return(MINMAX)
})), n=50)

YEAR     RN       DATE      NOM               SITE LONG                                                SP
1   2003 RNN027 2003-04-10 ESTAGNOL RNN027-Estagnol 01  540  Brintesia circe (Fabricius, 1775)
2   2003 RNN027 2003-04-10 ESTAGNOL RNN027-Estagnol 01  540  Carcharodus alceae (Esper, 1780)
3   2003 RNN027 2003-04-10 ESTAGNOL RNN027-Estagnol 01  540  Celastrina argiolus (Linnaeus, 1758)
4   2003 RNN027 2003-04-10 ESTAGNOL RNN027-Estagnol 01  540  Coenonympha dorus (Esper, 1782)
5   2003 RNN027 2003-04-10 ESTAGNOL RNN027-Estagnol 01  540  Coenonympha pamphilus (Linnaeus, 1758)

编辑 2:它现在正在工作,感谢您的帮助!

【问题讨论】:

    标签: r


    【解决方案1】:

    使用plyr 怎么样 - PS 如果您剩余的第 6-10 列对于任何 DATE/SITE 组合始终相同,那么可以进一步简化(不需要merge())

    require(plyr)
    
    sp<-read.csv("sp.csv")
    sp<-sp[,2:10] #(take out the ID numbers from csv)
    
    mins<-ddply(sp,.(YEAR,SITE,SP),summarise,DATE=min(DATE))
    mins<-merge(sp,mins,by=c("YEAR","SITE","DATE"))
    mins$DATE<-mins$DATE-7
    
    maxs<-ddply(sp,.(YEAR,SITE,SP),summarise,DATE=max(DATE))
    maxs<-merge(sp,maxs,by=c("YEAR","SITE","DATE"))
    maxs$DATE<-maxs$DATE+7
    
    sp.new<-rbind(mins,sp,maxs)
    sp.new[order(sp.new$DATE),]
    
       YEAR            SITE  DATE     RN      NOM   LONG                                     SP SUMNB     NB100
    1  2003 RNN027-Estagnol 12159 RNN027 ESTAGNOL 03 330 Anthocharis cardamines (Linnaeus,1758)     2 0.6060606
    7  2003 RNN027-Estagnol 12166 RNN027 ESTAGNOL 03 330 Anthocharis cardamines (Linnaeus,1758)     2 0.6060606
    12 2003 RNN027-Estagnol 12173 RNN027 ESTAGNOL 03 330 Anthocharis cardamines (Linnaeus,1758)     2 0.6060606
    2  2005 RNN027-Estagnol 12888 RNN027 ESTAGNOL 01 540 Anthocharis cardamines (Linnaeus,1758)     2 0.3703704
    10 2005 RNN027-Estagnol 12895 RNN027 ESTAGNOL 01 540 Anthocharis cardamines (Linnaeus,1758)     2 0.3703704
    11 2005 RNN027-Estagnol 12910 RNN027 ESTAGNOL 01 540 Anthocharis cardamines (Linnaeus,1758)     2 0.3703704
    13 2005 RNN027-Estagnol 12917 RNN027 ESTAGNOL 01 540 Anthocharis cardamines (Linnaeus,1758)     2 0.3703704
    3  2006 RNN027-Estagnol 13245 RNN027 ESTAGNOL 03 330 Anthocharis cardamines (Linnaeus,1758)     2 0.6060606
    8  2006 RNN027-Estagnol 13252 RNN027 ESTAGNOL 03 330 Anthocharis cardamines (Linnaeus,1758)     2 0.6060606
    9  2006 RNN027-Estagnol 13257 RNN027 ESTAGNOL 03 330 Anthocharis cardamines (Linnaeus,1758)     2 0.6060606
    14 2006 RNN027-Estagnol 13264 RNN027 ESTAGNOL 03 330 Anthocharis cardamines (Linnaeus,1758)     2 0.6060606
    4  2011 RNN027-Estagnol 15049 RNN027 ESTAGNOL 02 310 Anthocharis cardamines (Linnaeus,1758)     1 0.3225806
    5  2011 RNN027-Estagnol 15056 RNN027 ESTAGNOL 02 310 Anthocharis cardamines (Linnaeus,1758)     1 0.3225806
    6  2011 RNN027-Estagnol 15075 RNN027 ESTAGNOL 02 310 Anthocharis cardamines (Linnaeus,1758)     1 0.3225806
    15 2011 RNN027-Estagnol 15082 RNN027 ESTAGNOL 02 310 Anthocharis cardamines (Linnaeus,1758)     1 0.3225806
    

    【讨论】:

    • 这不是我想要的。例如,在第一个站点和第一年观察到了 27 个物种(ESTAGNOL,2003,在我的 DF 中看到)。您的命令检测到好的日期,但将它们与在该日期观察到的物种合并,对于这个例子只有 3 个物种,所以 3 分钟行而不是 27 行。我需要为每一年添加两个新行(最小和最大日期) /SITE/SP 组合。合并不符合这个想法。
    • 嗨@user2542995 - 如果你也想通过SP隔离,你需要做的就是更改创建最小和最大行的ddply()调用 - 他们的第二个参数需要从.(YEAR,SITE) 到 .(YEAR,SITE,SP)(误读你的问题是我的错)
    • 感谢您的回答,但它不适合我的问题。您的命令允许我隔离每个 SITE/YEAR/SPECIES 组合的第一个和最后一个 DATE,这不是我想要的。基本上,我需要获得年度观测范围的限制(所有物种总和的第一个和最后一个日期,我不知道)以创建零观测的虚拟数据。我知道如何获得它(使用 do.call),并且您的命令也这样做(每个 YEAR/SITE 块的 min 和 max(DATE))。我的意思是在我隔离的日期中添加 2*“按年份/地点组合的物种数量”虚拟行。
    • 您能否举例说明您希望结果表的外观?我有点理解困难!
    • 我更新了我的问题,但之后立即找到了解决方案。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 2021-08-04
    • 2017-09-16
    • 1970-01-01
    • 1970-01-01
    • 2018-06-10
    • 1970-01-01
    • 1970-01-01
    • 2015-08-09
    相关资源
    最近更新 更多