我正试着整理一些数据,最后一部分被清理掉了。
我需要做的是计算每个人(indivID)在几个月(6月、7月和8月)的观测次数,并为每个人返回一个百分比而不丢失数据,然后将这些观测值保持在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), ]
}
}
}
}发布于 2014-11-22 04:51:13
如果我正确地理解了你,你想保持每日观测的每一个组合的独立月-年,其中至少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,每一个独立月年有一行,覆盖范围至少75%。接下来,我们将把每日数据合并到这个数据框架中,为每个独特的indivID月-年的每日观察生成一行。
# 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)更新:以回答批注中的问题:
%>%是一个“链式”操作符,它允许您在运行下一个函数之前先将函数链起来,而不必存储前一个函数的结果。看看 Vignette,了解更多关于如何使用它的知识。下面是逻辑在本例中的工作方式:
group_by通过分组变量拆分数据集,然后在每个组上分别运行下一个函数。在本例中,summarise为indivID、month和year的每个唯一组合计算数据帧中的行数,然后mutate为该month和year的indivID添加一个具有小数覆盖范围的列。然后,filter将消除覆盖率低于75%的indivID、month和year的任何组合。你可以在任何时候停止链子,看看它在做什么。例如,运行以下代码,查看筛选操作之前的epa.d_75是什么样子:epa.d_75 = epa.d %>% group_by(indivID,年份,月份) %>%汇总(count=n()) %>%发生变异(pctCoverage= ifelse(month==6,count/30,count/31))
dplyr在隐藏的C代码中发挥了它的大部分魔力,这比本地R更快。希望其他人能给出一个更精确和详细的答案。发布于 2014-11-22 05:07:48
另一种选择是使用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)https://stackoverflow.com/questions/27074023
复制相似问题