基于R data.frame上多列的矢量化元数据计算

时间:2013-07-09 23:55:01

标签: r coding-style

我有一个包含3列的data.frame,每个列都可以被认为是一个因素。我想在data.frame上计算一些统计数据并将其存储在一个新的框架中。更具体地说,我有以下字段:

obs, len, src
A    10   X
B    10   Y

我想计算每个长度的每个来源的细分(即来自X的长度为10的观察的百分比是“A”,“B”等)。

一个明显的方法是使用两个for循环迭代长度和源,然后使用nrow()和count()来获取我需要计算的值,如下所示:

relevant_subset <- data[data$src==source & data$len==length,]
breakdown_info <- count(relevant_subset)
breakdown_info$frac <- breakdown_info$freq / nrow(relevant_subset)

有没有办法避免使用double for循环并使用更加向量化的方法?是否有一种智能的方法来预先分配新帧,该帧将保存每个长度和源的修改后的breakdown_info?

3 个答案:

答案 0 :(得分:2)

aggregate是您完成这些任务的朋友:

示例数据:

set.seed(23)
test <- data.frame(
  obs=sample(LETTERS[1:2],20,replace=TRUE),
  len=sample(c(10,20),20,replace=TRUE),
  src=sample(LETTERS[24:25],20,replace=TRUE)
)

汇总:

aggregate(obs ~ src + len,data=test, function(x) prop.table(table(x)))

  src len     obs.A     obs.B
1   X  10 0.6000000 0.4000000
2   Y  10 0.2000000 0.8000000
3   X  20 0.2500000 0.7500000
4   Y  20 0.1666667 0.8333333

答案 1 :(得分:1)

这是plyr包的制作!

格式为<input_type><output_type>ply。例如,如果输入为data.frame,并且您希望输出为data.frame,请使用ddply

要使用它,请指定输入data.frame,要分组的列,然后指定从每个组构造data.frame的函数。添加了分组列的结果data.frames将组合到输出data.frame中。

在类似于你的例子的情况下,你可以做到

require(plyr)
a <- data.frame(
    obs=factor(c('A','A','A','B','B')),
    len=c(10,10,10,10,210),
    src=factor(c('X','X','Y','Y','Z')))

然后

z <- ddply(
  a,
  .(obs),
  function(df){
    data.frame(mean.len=mean(df$len))
  })

会产生

data.frame(
  obs=c('A', 'B'),
  mean.length(10, 110))

,而

ddply(a, .(src), function(df){
  data.frame(
    num.obs.A = sum(df$obs == 'A'),
    num.obs.B = sum(df$obs == 'B'))})

会产生

data.frame(
  src=c('X','Y', 'Z'),
  num.obs.A = c(3,1,0),
  num.obs.B = c(0,1,1))  

网站http://plyr.had.co.nz/也有很好的文档。

答案 2 :(得分:0)

您还没有说明您希望将data.frame作为输出的原因。对你来说也许是最好的,也许不是。你也不清楚什么比例是什么,但我认为以下可能最好地解决你的问题。

prop.table( table(test) )

您可以略微不同地输入它并按列的顺序播放,以便最容易检查您想要比较的内容。但是,这个输出是一个三维数组,与data.frame有很大的不同。

(替代用法示例)

prop.table(with(test, table(src, obs, len) ))