我正在尝试对一些数据进行分配,并且仍然停留在清洁的最后部分。
我需要做的是计算每个人(6月,7月和8月)的每个人(indivID)的观察数量,并返回每个人的百分比而不丢失数据,然后保持这些观察结果超过75%。
我能够创建一个嵌套的for循环,但今天花了大约6个小时来处理。我希望能够通过使用ddply或其他功能来利用并行计算机,但非常丢失。
这是数据(注意这是一个非常小的子集,仅包括1:5的个体): https://www.dropbox.com/s/fmk8900622klsgt/data.csv?dl=0
这是for循环:
epa.d <- read.csv("/.../data.csv")
#Function for loops
days <- function (month){
if (month == 06) return(as.numeric(30))
if (month == 07) return(as.numeric(31))
if (month == 08) return(as.numeric(31))
}
#Subset data for 75% in June, July, and August
for (i in unique(epa.d$indivID)){
for (j in unique(epa.d$year)){
for (k in unique(epa.d$month)){
monthsum <- sum(epa.d$indivID == i & epa.d$year == j & epa.d$month == k )
monthperc = (monthsum/days(k))* 100
if (monthperc < 75){
epa.d <- epa.d[! (epa.d$indivID == i & epa.d$year == j), ]
}
}
}
}
答案 0 :(得分:2)
如果我理解正确,您希望每天对每个组合进行日常观察,其中至少有75%的天数进行臭氧测量。这是一种应该非常快的方法:
library(dplyr)
# For each indivID, calculate percent of days in each month with
# ozone observations, and keep those with pctCoverage >= 0.75
epa.d_75 = epa.d %>%
group_by(indivID, year, month) %>%
summarise(count=n()) %>%
mutate(pctCoverage = ifelse(month==6, count/30, count/31)) %>%
filter(pctCoverage >= 0.75)
我们现在有一个数据框epa.d_75
,每个indivID-month-year有一行,覆盖率至少为75%。接下来,我们将每日数据合并到此数据框中,从而为每个独特的indivID-month-year每日观察一行。
# Merge in daily data for each combination of indivID-month-year that meets
# the 75% coverage criterion
epa.d_75 = merge(epa.d_75, epa.d, by=c("indivID","month","year"),
all.x=TRUE)
更新:要回答提交中的问题:
你能解释一下%&gt;%正在做什么,如果可能的话,你可以分解逻辑思考这个问题的方法。
%>%
是一个&#34;链接&#34;运算符,允许您一个接一个地链接函数,而不必在运行下一个函数之前存储上一个函数的结果。请查看dplyr
Vignette以了解有关如何使用它的更多信息。以下是逻辑在这种情况下的工作原理:
group_by
通过分组变量拆分数据集,然后分别在每个组上运行下一个函数。在这种情况下,summarise
计算indivID
,month
和year
的每个唯一组合的数据框中的行数,然后mutate
添加包含indivID
和month
的{{1}}小数覆盖率的列。 year
然后删除filter
,indivID
和month
的任意组合,覆盖率低于75%。您可以随时停止链条,看看它在做什么。例如,运行以下代码以查看过滤操作之前的year
内容:
epa.d_75
epa.d_75 = epa.d %>%
group_by(indivID, year, month) %>%
summarise(count=n()) %>%
mutate(pctCoverage = ifelse(month==6, count/30, count/31))
在dplyr
代码中完成了大部分的魔术,这比原始C
更快。希望其他人可以提供更精确和详细的答案。答案 1 :(得分:2)
另一种选择是使用data.table
(类似于@ eipi10的dplyr
方法),这将非常快。
library(data.table)
epa.d_75 <- setDT(epa.d)[, list(pctCoverage=ifelse(month==6, .N/30,
.N/31)),by=list(indivID, year, month)][pctCoverage >=0.75]
epa.d_75New = merge(epa.d_75, epa.d, by=c("indivID","month","year"),
all.x=TRUE)
epa.d <- read.csv('data.csv', row.names=1)