我在网站上读过很多关于根据日期随机对大型数据集进行子集观测的帖子——第一个、最后一个或特定日期。然而,我有一个不同的挑战,要求我按站点和日期对大型数据集进行子采样。我想将所有站点保留在子集数据集中,但每个站点只包括1个日期观测。
更具体地说,我有一个4年昆虫群落观测(n=2000)的大型数据集(用于群落生态学!)。它们是从大约900个站点中观察到的,但每个站点在一年内都有1到6个日期观测,在几年之间没有重复的站点(这就是为什么以前想要划分特定日期范围的帖子不能应用于此)。这种特殊方式的子集是至关重要的,因为我正在使用的统计分析类型——在分析中包括空间自相关项意味着我每个站点只能包括一个观测。
因此,完整的数据集看起来像:
Site Date Ladybug
Baumgarten 6/24/2014 2
Baumgarten 8/6/2014 0
Baumgarten 8/20/2014 3
Baumgarten 7/8/2014 0
Baumgarten 7/22/2014 1
Berkevich 7/9/2014 0
Berkevich 7/23/2014 4
Berkevich 8/8/2014 0
Berkevich 8/22/2014 0
Boehm 6/24/2014 2
# dput(data)
dd <- structure(list(Site = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L), .Label = c("Baumgarten", "Berkevich", "Boehm"), class = "factor"), Date = structure(c(1L, 8L, 6L, 4L, 2L, 5L, 3L, 9L, 7L, 1L), .Label = c("6/24/2014", "7/22/2014", "7/23/2014", "7/8/2014", "7/9/2014", "8/20/2014", "8/22/2014", "8/6/2014", "8/8/2014" ), class = "factor"), Ladybug = c(2L, 0L, 3L, 0L, 1L, 0L, 4L, 0L, 0L, 2L)), .Names = c("Site", "Date", "Ladybug"), class = "data.frame", row.names = c(NA, -10L))
我想要的子集数据集看起来像:
Site Date Ladybugs
Baumgarten 8/20/2014 3
Berkevich 7/9/2014 0
Boehm 6/24/2014 2
我以MM/DD/YYYY和DOY格式输入了日期(由于站点在年份之间不会重复,DOY x站点子集仍然可以工作,以确保没有重复的站点),因此使用这两种格式的代码都可以工作。
任何建议都将不胜感激。谢谢
假设您的数据是名为df
的data.frame
,则可以使用dplyr
并执行以下操作:
library(dplyr)
df %>%
group_by(Site) %>%
sample_n(1)
# Source: local data frame [3 x 3]
# Groups: Site [3]
#
# Site Date Ladybug
# (fctr) (fctr) (int)
# 1 Baumgarten 8/20/2014 3
# 2 Berkevich 8/22/2014 0
# 3 Boehm 6/24/2014 2
使用data.table
可以使用:
require(data.table)
setDT(DT)
DT[,.SD[sample(.N,1)], by=Site]
这会给你
Site Date Ladybug
1: Baumgarten 8/20/2014 3
2: Berkevich 7/23/2014 4
3: Boehm 6/24/2014 2
您也可以使用base-R。它按站点拆分数据,对一行进行采样并返回。然后结果就结合在一起了。
set.seed(123)
res <- do.call(rbind,lapply(split(dat,dat$Site),function(x){x[sample(nrow(x),1),]}))
另一种可能性是数据表:
library(data.table)
setDT(dat)
set.seed(123)
res <- dat[,.SD[sample(.N,1)],Site]
这可能是一种效率低下的方法,但它可以完成任务。
levels <- length(unique(data$Site))
rowselect<- sapply(1:levels, function(x) {
elem <- which(array==unique(array)[x])
if(length(elem)<2){
return(elem)
} else {
return(sample(elem,1))
}
})
这为每个站点随机选择的1行提供了rowindex。