我用CSV格式获得了这个表/数组:
GroupID Channel Daysbeforelast
1 A 35
1 B 31
1 C 29
1 D 17
1 E 15
1 D 5
1 C 0
2 B 66
2 E 17
2 D 15
2 A 2
2 C 0
2 F 0
2 A 0
4 B 15
4 C 0
并尝试再添加一列Weight
,以便表格如下所示:
GroupID Channel Daysbeforelast Weight How it is calculated
1 A 35 0.00005 (1-x/2/2-x/2-x)/2
1 B 31 0.00005 (1-x/2/2-x/2-x)/2
1 C 29 0.0833 (x/2/2)/3
1 D 17 0.0833 (x/2/2)/3
1 E 15 0.0833 (x/2/2)/3
1 D 5 0.25 (x/2)
1 C 0 0.5 (x)
2 B 66 0.125 (1-x/2/2-x/2-x)
2 E 17 0.0625 (x/2/2)/2
2 D 15 0.0625 (x/2/2)/2
2 A 2 0.25 (x/2)
2 C 0 0.25 (x)/3
2 F 0 0.25 (x)/3
2 A 0 0.5 (x)/3
4 B 15 0.5 (1-x)
4 C 0 0.5 (x)
下面解释说明:
每个组可以有一个或多个子组,具体取决于数据:
如果Daysbeforelast=0
则为Subgroup1;
如果0<Daysbeforelast<=7
则为Subgroup2;
如果7<Daysbeforelast<=14
则为Subgroup3;
如果14<Daysbeforelast<=30
则为Subgroup4;
Else Subgroup5。
第一个子组有weight = x
(例如x = 0.5)。此weight
均匀分布在组中子组的所有行中。让我们说组Y在SubgroupZ中有3行。在这种情况下,每一行都有weight equal (SubgroupZ weight)/3
。
Subgroup2有weight = x/2
,它以相同的方式分布在该子组的所有行中。
直到最后一个子组的每个子组将获得等于前一个子组的weight
的{{1}}除以2。
组中的最后一个子组(它不总是子组5)将收到组中所有先前权重的weight
。
这是为了检查每组的权重总和是否等于1。
请注意,如果我们在Subgroup2中没有任何行,那么Subgroup3将会收到weight = 1 - sum
(而不是x / 2/2)。
我们为所有组都设置了Subgroup1,但是所有或任何其他子组都可能丢失。
最简单的方法可能是使用lapply变量,但我得到了堆栈,因为我对R来说很新。
答案 0 :(得分:2)
以下是解决方案:对于每个组,使用cut
标识子组,并使用droplevels
删除缺席子组。将权重分配为(x/2^n)/freq
。然后确定最小权重并调整它们,使得组中的权重总和加起来为1。
dat <- read.table("clipboard", header = T)
groupIDs <- unique(dat$GroupID)
x = 0.5
for (i in groupIDs)
{
rows = which(dat$GroupID == i)
Subgroups <- cut(dat[rows,3], c(-Inf,0,7,14,30,Inf), labels = 1:5)
a<-droplevels(Subgroups)
wts <- sapply(a,function(y)(x/(2^(as.numeric(y)-1)))/(table(a)[which(levels(a) == y)]))
ind <- wts==min(wts)
wts[ind] <- (1-sum(wts[!ind]))/sum(ind)
dat[rows,4] <- wts
}
names(dat)[4] <- "Weight"