1

我有一个包含 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)

有没有办法避免使用双 for 循环并使用更矢量化的方法?有没有一种聪明的方法来预先分配新的帧来保存每个长度和源的修改后的故障信息?

4

3 回答 3

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
于 2013-07-10T00:18:02.273 回答
1

这就是plyr包装的目的!

格式为<input_type><output_type>ply. 例如,如果输入是 adata.frame并且您希望输出是data.frameuse ddply

要使用它,您需要指定 input data.frame、要分组的列,然后指定一个data.frame从每个组构造 a 的函数。附加了分组列的结果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/也有很好的文档。

于 2013-07-10T21:12:28.617 回答
0

您还没有说明为什么要在此处使用 data.frame 作为输出的原因。也许它对你最好,也许不是。您也不清楚什么是什么比例,但我认为以下内容可能最好地解决您的问题。

prop.table( table(test) )

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

(替代用法示例)

prop.table(with(test, table(src, obs, len) ))
于 2013-07-10T22:01:03.333 回答