如何通过循环传递 Dataframe 列表

m528fe3b  于 2023-05-04  发布在  其他
关注(0)|答案(1)|浏览(119)

我有一个年度动物跟踪数据集的列表,我试图计算家庭范围估计。我有一个循环,将计算每个年度数据集的家庭范围估计,但我想做的是能够通过循环提供两个年度数据集,并为每个 Dataframe 获取MCP对象。
下面是一个到目前为止我的代码的例子,使用了ctmm包中内置的布法罗数据。第一个块只是读入并正确格式化数据。不需要对这一部分进行故障排除,只需要为本地范围环路准备好数据。

library(ctmm) 
library(ggplot2) 
library(dplyr) 
library(stringr) 
library(lubridate) 
library(sf) 
library(tidyverse) 
library(sp) 
library(scales) 
library(tidyr) 
library(tibble)

###########DATA CLEANING STEPS (Already works, no need to focus on)#################################
#Load the data
data("buffalo")

#Creating individual dataframes and adding an id column
Cilla <- as.data.frame(buffalo$Cilla) 
Cilla$id<-"Cilla"

Gabs<-as.data.frame(buffalo$Gabs)
Gabs$id<-"Gabs"

Mvubu<-as.data.frame(buffalo$Mvubu)
Mvubu$id<-"Mvubu"

Pepper<-as.data.frame(buffalo$Pepper)
Pepper$id<-"Pepper"

Queen<-as.data.frame(buffalo$Queen)
Queen$id<-"Queen"

Toni<-as.data.frame(buffalo$Toni)
Toni$id<-"Toni"

#Combining dataframes and adding a year, UTM zone, and date column
buffalo2 <- rbind(Cilla,Gabs,Mvubu,Pepper,Queen,Toni)
buffalo2$Year<-year(buffalo2$timestamp)
buffalo2$Year<-as.factor(buffalo2$Year)
buffalo2$UTM.zone<-"12 +datum=NAD27"
buffalo2$timestamp <- ymd_hms(buffalo2$timestamp) 
buffalo2$Timestamp<-buffalo2$timestamp
buffalo2 <- separate(buffalo2, timestamp, c("date","time"), sep= " ", remove= TRUE, extra= "merge")

#Reordering columns
buffalo2 <- buffalo2[, c(8,9,1,2,6,7,11,10)]

#Splitting data by year
data2005<-buffalo2 %>% 
  filter(Year==2005)
data2006<-buffalo2 %>% 
  filter(Year==2006)

#Creating annual telemetry data
Tdata2005<-as.telemetry(data2005, timeformat="auto",timezone="UTC", 
                        timeout=Inf,datum="NAD27",
                        na.rm="row",mark.rm=FALSE,keep=FALSE,drop=FALSE)
Tdata2006<-as.telemetry(data2006, timeformat="auto",timezone="UTC", 
                        timeout=Inf,datum="NAD27",
                        na.rm="row",mark.rm=FALSE,keep=FALSE,drop=FALSE)

#Creating a list of telemetry data
Tdata<-list(Tdata2005,Tdata2006)
names(Tdata)<-c("Tdata2005","Tdata2006")

这是我的循环,它能够计算单个年度 Dataframe 的MCP家庭范围估计(例如:Tdata2005)。

#Load adehabitat package
library(adehabitatHR)

#buffalo MCP loop
buffalo.sp<-list()
MCP<-list()
for(i in 1:length(Tdata2005)){
  X<-Tdata2005[[i]][[5]]
  Y<-Tdata2005[[i]][[6]]
  ID<-names(Tdata2005)
  XY <- data.frame(X, Y)
  buffalo.sp[[i]]<-data.frame(ID[[i]],X,Y)
  coordinates(buffalo.sp[[i]]) <- c('X', 'Y')
  MCP[[i]]<-mcp(buffalo.sp[[i]], percent=95)
  plot(buffalo.sp[[i]], col=as.factor(buffalo.sp[[i]]@data$ID),pch=16,main=paste("MCP_",names((Tdata2005[i]))),axes=TRUE)+
    plot(MCP[[i]], col=alpha(1:13,0.5),add=TRUE)
}
names(buffalo.sp)<-names(Tdata2005)
names(MCP)<-names(Tdata2005)

我现在想做的是弄清楚如何通过循环运行整个 Dataframe 列表(Tdata)(可能是一个包含循环的函数?)),以获得两个年度 Dataframe (Tdata 2005和Tdata 2006)中所有个体的MCP估计值。你知道我该怎么做吗?谢谢!

mf98qq94

mf98qq941#

将代码 Package 在一个函数中,然后在list上循环并应用该函数会更容易

library(adehabitatHR)
f1 <- function(tdata)
{
buffalo.sp<-list()
MCP<-list()
for(i in 1:length(tdata)){
  X<-tdata[[i]][[5]]
  Y<-tdata[[i]][[6]]
  ID<-names(tdata)
  XY <- data.frame(X, Y)
  buffalo.sp[[i]]<-data.frame(ID[[i]],X,Y)
  coordinates(buffalo.sp[[i]]) <- c('X', 'Y')
  MCP[[i]]<-mcp(buffalo.sp[[i]], percent=95)
  plot(buffalo.sp[[i]], col=as.factor(buffalo.sp[[i]]@data$ID),
    pch=16,main=paste("MCP_",names((Tdata2005[i]))),axes=TRUE)+
    plot(MCP[[i]], col=alpha(1:13,0.5),add=TRUE)
}
names(buffalo.sp)<-names(tdata)
names(MCP)<-names(tdata)
return(list(buffalo.sp = buffalo.sp, MCP = MCP))

}

out <- vector('list', length(Tdata))
 for(i in seq_along(out)) out[[i]] <- f1(Tdata[[i]])
  • 输出
> str(out)
List of 2
 $ :List of 2
  ..$ buffalo.sp:List of 5
  .. ..$ Cilla:Formal class 'SpatialPointsDataFrame' [package "sp"] with 5 slots
  .. .. .. ..@ data       :'data.frame':    3527 obs. of  1 variable:
  .. .. .. .. ..$ ID..i..: chr [1:3527] "Cilla" "Cilla" "Cilla" "Cilla" ...
  .. .. .. ..@ coords.nrs : int [1:2] 2 3
  .. .. .. ..@ coords     : num [1:3527, 1:2] 29080 25856 26454 27045 26350 ...
...

相关问题