按因子将相对频率添加到数据帧

时间:2014-06-08 13:38:03

标签: r data.table

我想在数据框中添加一个列,其中相对频率按因子(Var2)

X = structure(list(Var1 = structure(c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 
                                      8L, 9L, 10L, 11L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L
), .Label = c("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", 
              "10"), class = "factor"), Var2 = structure(c(1L, 1L, 1L, 1L, 
                                                           1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
                                                           2L, 2L), .Label = c("No Treatment", "Any Treatment"), class = "factor"), 
Freq = c(1L, 3L, 6L, 13L, 30L, 53L, 69L, 123L, 198L, 270L, 
         1324L, 1L, 0L, 4L, 10L, 16L, 33L, 44L, 75L, 113L, 159L, 630L
)), .Names = c("Var1", "Var2", "Freq"), row.names = c(NA, 
                                                      -22L), class = "data.frame")

我想到的解决方案非常复杂,而且不够灵活。这就是我现在正在做的事情:

library(data.table)
DT =data.table(X)

myfun <- function (freq, group, total1, total2) 
{
  if(group[[1]] == "No Treatment"){
    relfreq = freq/total1
  }else{
    relfreq = freq/total2
  }
  return(relfreq)
}

DT[,relfreq:=myfun(Freq,Var2,sum(DT$Freq[DT$Var2=="No Treatment"]), sum(DT$Freq[DT$Var2=="Any Treatment"]))]

有人可以向我展示一个更灵活的更好的解决方案,并允许Var2获取超过2个值吗?

谢谢!

2 个答案:

答案 0 :(得分:2)

这是一个数据表解决方案,因为你就是这样开始的。

DT[,relfreq:=Freq/sum(Freq),by=Var2]

如果数据集非常大,这将会更快,主要是因为数据表通过引用添加新列,而不是复制整个数据集。

答案 1 :(得分:1)

你可以通过ave得到一个和的向量,并用这个向量除X$Freq

X$relfreq <- X$Freq / ave(X$Freq, X$Var2, FUN=sum)

甚至:

X$relfreq  <- ave(X$Freq, X$Var2, FUN=function(x) x/sum(x))

请注意,您的函数不正确,并在示例中将每个Freq除以2090,而不是除以每个因子级别Freq的总和。