【发布时间】:2019-04-26 21:10:09
【问题描述】:
我有一个数据框,其中包含许多不同的动物(以下示例数据中的 a、b、c)、transactionID、计数和天数。我想计算每个动物内每个 transactionID 的增加时间窗口(按天指定)的计数值的平均值和标准偏差。即对于动物a的事务ID 1,我想为i)天-1到-2,ii)天-1到-3,iii)天-1到-4等的平均值和标准差添加列......所以我最终得到了 5 个新列,增加了时间窗口,5 个用于 SD。
示例数据:
> dput(df)
structure(list(Animal = c("a", "a", "a", "a", "a", "a", "a", "a",
"a", "a", "a", "b", "b", "b", "b", "b", "b", "b", "c", "c", "c",
"c", "c"), Count = c(45L, 54L, 22L, 3L, 23L, 46L, 45L, 22L, 67L,
34L, 22L, 34L, 677L, 86L, 54L, 4L, 56L, 98L, 23L, 54L, 22L, 77L,
23L), Day = c(-6L, -5L, -4L, -3L, -2L, -1L, -5L, -4L, -3L, -2L,
-1L, -4L, -3L, -2L, -1L, -3L, -2L, -1L, -6L, -5L, -3L, -2L, -1L
), transactionID = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L)), .Names = c("Animal",
"Count", "Day", "transactionID"), class = "data.frame", row.names = c(NA,
-23L))
> df
Animal Count Day transactionID
1 a 45 -6 1
2 a 54 -5 1
3 a 22 -4 1
4 a 3 -3 1
5 a 23 -2 1
6 a 46 -1 1
7 a 45 -5 2
8 a 22 -4 2
9 a 67 -3 2
10 a 34 -2 2
11 a 22 -1 2
12 b 34 -4 3
13 b 677 -3 3
14 b 86 -2 3
15 b 54 -1 3
16 b 4 -3 4
17 b 56 -2 4
18 b 98 -1 4
19 c 23 -6 5
20 c 54 -5 5
21 c 22 -3 5
22 c 77 -2 5
23 c 23 -1 5
我可以使用下面的代码实现我想要的输出。但是,当循环遍历我的整个数据框时,有些情况下我的动物时间少于 6 天,并且在最大编号的情况下,此 for 循环不会添加 NA。数据集中的天数(因此时间窗口)小于 6。我的数据集中还有一些案例,其中日列中缺少一天(即动物 c,第 -4 天)。在这种情况下,我想从丢失的那一天开始为所有时间窗口添加均值和 sds 的 NA。请参阅下面的我想要的输出。
我的尝试:
#create empty matrix
res2 = as.data.frame(matrix(NA,0,14))
#split by name
animal.list = split(df,df$Name)
#For loop for
for(i in 1:length(animal.list)){
a = as.data.frame(animal.list[[i]])
animal = unique(a$Name)
#create empty matrix
res = as.data.frame(matrix(NA,0,14))
#create list of event IDs
event = split(a,a$transactionID)
#loop through each event in turn and calculate the mean of different baseline periods (from 2 days to 6 days)- clunky!
for(j in 1:length(event)){
e = as.data.frame(event[[j]])
#max day
e$maxday = unique(e[1,]$Day)
#save mean activity value for the 2 days prior to event
e$mean2d = round(mean(e[e$Day >-3,]$Count),3)
e$SD2d = round(sd(e[e$Day >-3,]$Count),3)
#save mean activity value for the 3 days prior to event
e$mean3d = round(mean(e[e$Day >-4,]$Count),3)
e$SD3d = round(sd(e[e$Day >-4,]$Count),3)
#save mean activity value for the 4 days prior to event
e$mean4d = round(mean(e[e$Day >-5,]$Count),3)
e$SD4d = round(sd(e[e$Day >-5,]$Count),3)
#save mean activity value for the 5 days prior to event
e$mean5d = round(mean(e[e$Day >-6,]$Count),3)
e$SD5d = round(sd(e[e$Day >-6,]$Count),3)
#save mean activity value for the 6 days prior to event
e$mean6d = round(mean(e[e$Day >-7,]$Count),3)
e$SD6d = round(sd(e[e$Day >-7,]$Count),3)
res = rbind(res,e)
}
res2 = rbind(res2,res)
}
期望的输出:
>res2
Name Count Day transactionID maxday mean2d SD2d mean3d SD3d mean4d SD4d mean5d SD5d
1 a 45 -6 1 -6 34.5 16.263 24.000 21.517 23.50 17.597 29.6 20.452
2 a 54 -5 1 -6 34.5 16.263 24.000 21.517 23.50 17.597 29.6 20.452
3 a 22 -4 1 -6 34.5 16.263 24.000 21.517 23.50 17.597 29.6 20.452
4 a 3 -3 1 -6 34.5 16.263 24.000 21.517 23.50 17.597 29.6 20.452
5 a 23 -2 1 -6 34.5 16.263 24.000 21.517 23.50 17.597 29.6 20.452
6 a 46 -1 1 -6 34.5 16.263 24.000 21.517 23.50 17.597 29.6 20.452
7 a 45 -5 2 -5 28.0 8.485 41.000 23.302 36.25 21.266 38.0 18.828
8 a 22 -4 2 -5 28.0 8.485 41.000 23.302 36.25 21.266 38.0 18.828
9 a 67 -3 2 -5 28.0 8.485 41.000 23.302 36.25 21.266 38.0 18.828
10 a 34 -2 2 -5 28.0 8.485 41.000 23.302 36.25 21.266 38.0 18.828
11 a 22 -1 2 -5 28.0 8.485 41.000 23.302 36.25 21.266 38.0 18.828
12 b 34 -4 3 -4 70.0 22.627 272.333 350.817 212.75 310.240 NA NA
13 b 677 -3 3 -4 70.0 22.627 272.333 350.817 212.75 310.240 NA NA
14 b 86 -2 3 -4 70.0 22.627 272.333 350.817 212.75 310.240 NA NA
15 b 54 -1 3 -4 70.0 22.627 272.333 350.817 212.75 310.240 NA NA
16 b 4 -3 4 -3 77.0 29.698 52.667 47.089 NA NA NA NA
17 b 56 -2 4 -3 77.0 29.698 52.667 47.089 NA NA NA NA
18 b 98 -1 4 -3 77.0 29.698 52.667 47.089 NA NA NA NA
19 c 23 -6 5 -6 50.0 38.184 NA NA NA NA NA NA
20 c 54 -5 5 -6 50.0 38.184 NA NA NA NA NA NA
21 c 22 -3 5 -6 50.0 38.184 NA NA NA NA NA NA
22 c 77 -2 5 -6 50.0 38.184 NA NA NA NA NA NA
23 c 23 -1 5 -6 50.0 38.184 NA NA NA NA NA NA
mean6d SD6d
1 32.167 19.343
2 32.167 19.343
3 32.167 19.343
4 32.167 19.343
5 32.167 19.343
6 32.167 19.343
7 NA NA
8 NA NA
9 NA NA
10 NA NA
11 NA NA
12 NA NA
13 NA NA
14 NA NA
15 NA NA
16 NA NA
17 NA NA
18 NA NA
19 NA NA
20 NA NA
21 NA NA
22 NA NA
23 NA NA
编辑:基于@Henrik 的建议(这是一种更快的方法来计算累积均值和广告,但仍然没有考虑缺失的情况天并在这些情况下使用 Has)- 任何简单的建议将不胜感激):
library(dplyr)
library(TTR)
#create empty matrix
res2 = as.data.frame(matrix(NA,0,14))
#split by name
animal.list = split(df,df$Name)
#For loop for
for(i in 1:length(animal.list)){
a = as.data.frame(animal.list[[i]])
animal = unique(a$Name)
#create empty matrix
res = as.data.frame(matrix(NA,0,14))
#create list of event IDs
event = split(a,a$transactionID)
#loop through each event in turn and calculate the mean of different baseline periods (from 2 days prior to 10 days prior)
for(j in 1:length(event)){
e = as.data.frame(event[[j]])
#max day
e$maxday = unique(e[1,]$Day)
cmean = cummean(rev(e$Count))
csd= runSD(rev(e$Count),n=1,cumulative=TRUE)
e$mean2d = cmean[2]
e$sd2d = csd[2]
e$mean3d = cmean[3]
e$sd3d = csd[3]
e$mean4d = cmean[4]
e$sd4d = csd[4]
e$mean5d = cmean[5]
e$sd5d = csd[5]
e$mean6d = cmean[6]
e$sd6d = csd[6]
res = rbind(res,e)
}
res2 = rbind(res2,res)
}
【问题讨论】:
-
@Henrik - 谢谢你的这些建议。非常有帮助,这给了我想要的一切输出,除了考虑缺少一天的情况。您能否就如何将其合并到上面的 forloop 编辑中提出建议?任何帮助将不胜感激。谢谢!
-
@jjulip 你看过我的回答了吗?它与您想要的输出完全匹配,而且更简单。
-
@arg0naut 是的,非常感谢。我一直在努力解决它。我只是无法通过代码,因为它对我来说太先进了。即请在下面查看我的问题。我真的很想提高我的 R 技能,但是很难用大量的 ifelses 分解大功能,而且我需要时间!谢谢你的帮助。
-
警告:切勿在循环中使用
rbind!这会导致过度复制!见R Inferno: Growing Objects。