带条件的乘法

时间:2013-08-29 06:15:29

标签: r conditional multiplication

假设数据框具有以下结构:

x=c(1:18)
y=c(9:26)
k=c(NA)
id=c(1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3)
task=c(1,1,2,2,2,3,3,1,1,1,2,2,2,1,1,2,2,2)
alts=c(2,3,1,2,3,1,3,1,2,3,1,2,3,1,2,1,2,3)

data<-data.frame(id, task, alts, x, y, k)

现在我想用不同的条件乘以x和y,即

  1. 当id == i和task == j,prod(x);
  2. 当id == i和task!= j,prod(y);
  3. 当id == i,prod(y)。
  4. 然后k = prod(x)* prod(y)/(1-prod(y))。该等式中的第一个产品(y)来自条件2,第二个产品(y)来自条件3.

    例如,假设我想计算k [1](表示id == 1和task == 1),则k [1] =(x [1] * x [2])*(y [ 3] * y [4] * y [5] * y [6] * y [7])/(1 - y [1] * y [2] * ... * y [7])。 k [2] = k [1]因为数据中的k [2]也表示id == 1且task == 1的条件。

    我使用的代码是:

    for (i in 1:3){ # for each individual
    
      for(j in 1:3){ # for each task of each individual
    
        data1=ddply(data, .(id, task), transform, k=prod(x[id==i & task==j])*prod(y[id==i & task!=j])/(1-prod(y[id==i])))
      }
    }
    

    我尝试了这段代码,但它没有用。为什么函数 prod(x-condition 1)* prod(y-condition 2)/ prod(y-condition 3)不起作用?有人可以帮帮我吗?

2 个答案:

答案 0 :(得分:0)

好的,让我们试试这个,基于@leif的评论。我在您的数据框中创建了一个新元素:

data$calc<- data$x*(data$id==ii & data$task==jj) * data$y*(data$id==ii & data$task!=jj)/ (1-(data$y*(data$id==ii)))

现在,对于您的示例数据,这几乎总是出现零。也许您想使用prod(x)返回1作为空向量的事实?我的计算将xy设置为零,因此必须修改为

data$calc<- max(1,data$x*(data$id==ii & data$task==jj)) * max(1,data$y*(data$id==ii & data$task!=jj))/ (1-(max(1,data$y*(data$id==ii))))

如果您的数据集中有任何负数,那么当然会不高兴。

编辑:您写道,您想要获取符合i,j标准的所有x的产品,所以我相信这会有效。因为我把“剪贴板”留在了另一个地方,所以它来自记忆:

data$calc<- prod(data$x[data$id==ii & data$task==jj)]) * prod(data$y[(data$id==ii & data$task!=jj)])/ (1-prod(data$y[(data$id==ii)]) )

答案 1 :(得分:0)

我认为部分地这样做可能是最清楚的。我们可以单独计算每个产品,然后将它们组合在一起。这在计算上并不是最优的,但希望它非常易读。我将使用您的示例数据集作为输入:

x=c(1:18)
y=c(9:26)
k=c(NA)
id=c(1,1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3)
task=c(1,1,2,2,2,3,3,1,1,1,2,2,2,1,1,2,2,2)
alts=c(2,3,1,2,3,1,3,1,2,3,1,2,3,1,2,1,2,3)

data<-data.frame(id, task, alts, x, y, k)

我在这里给出的方法是分别计算prod(x by id and task)prod(y by id and task)prod(y by id),然后在最后将它们合并。

x.y.by.id.task <- aggregate(data.frame(x.id.task=data$x, y.id.task=data$y),
                            data[c("id", "task")], 
                            prod)
y.by.id      <- aggregate(data.frame(y.id=data$y), 
                          data["id"], 
                          prod)

现在x.y.by.id.task包含id和任务组合的x和y产品,y.by.id包含y by id的乘积。我们可以将它们组合成一个数据帧,并使用一个矢量化操作进行最终计算。

id.task <- merge(x.y.by.id.task, y.by.id)

id.task$result <- 
  id.task$x.id.task * # prod(x by id by task)
  (id.task$y.id / id.task$y.id.task) / # prod(y by id and !task)
  (1 - id.task$y.id) # 1 - prod(y by id)

现在,在大型数据集中,这种方法在计算上并不是最优的,并且根据您的问题设置,您可能会遇到数值不稳定。但这对于许多问题设置应该足够了。这个解决方案很不错,因为R完成了查找id和任务组合以及为你安排输出的繁重工作。

此外,这仅计算数据集中存在的id和任务组合的值。在您的情况下,没有id = 3,task = 3组合。如果你检查最后的id.task data.frame,你会发现没有行id = 3和task = 3(因为没有行在数据中这是真的)。​​

希望有所帮助!