【问题标题】:How to tabulate columns in a data frame and put the results in a single data frame如何将数据框中的列制成表格并将结果放入单个数据框中
【发布时间】:2017-02-06 15:04:14
【问题描述】:

我有一个400行1200列的数据框,大致结构是这样的:

> df=data.frame(Col1=paste0('row',1:15),metric1=sample(c('H','M','L'),15,replace = 1),metric2=sample(c('H','M'),15,replace = 1))
> df
    Col1 metric1 metric2 ...
1   row1       M       H
2   row2       H       L

我想做的是根据每列的 HML 计数比较每行的表格结果。

我试过了

> apply(df[,2:3],2,function(x) table(x))
$metric1
x
H L M 
1 7 7 

$metric2
x
 H  M 
10  5 

> 

但结果是一个 1200 的列表,因为并非所有列都包含所有 3 个值,即一列只有 HL,而另一列将具有 HML。

我也试过聚合,结果报错

> apply(df[,2:3],2,function(x) aggregate(df$count,list(df[,x]),sum))
Error in `[.data.frame`(df, , x) : undefined columns selected

但我的功能有效:

> aggregate(df$count,list(df[,2]),sum)
  Group.1 x
1       H 1
2       L 7
3       M 7
> 

我希望将其保存为数据框,例如:

> data.frame(var=c('H','M','L'),metric1=c(100,100,200),metric2=c(250,150,0))
  var metric1 metric2
1   H     100     250
2   M     100     150
3   L     200       0
> 

【问题讨论】:

  • 您只有这 3 个类别(H、L、M)还是更一般的类别?

标签: r aggregate apply


【解决方案1】:

或者如果你不想使用循环,你也可以在表格函数中分配级别:

apply(df[,2:3],2,function(x) table(factor(x,levels=c("H","M","L"))))

    metric1 metric2
H       6      11
M       8       4
L       1       0

【讨论】:

  • 请注意,apply 在后台使用 for 循环,通常比正确实现的 for 循环慢。
  • 谢谢,lmo!我不知道!但是,如果另一个解决方案然后在 for 循环之后调用 sapply,它还会更快吗(如果可能 sapply 仍在后台运行 for 循环)?感谢您的任何见解! :)
  • 标准答案是视情况而定。 apply 的第二个“问题”是它在实现提供的函数之前将其主要参数(的副本)转换为矩阵。在这里,这涉及从因子列表到字符向量矩阵的转换,然后将其列重新转换为因子,一次一个。这是对大型数据集的一组相当昂贵的操作,for 循环可以避免。您可以使用apply(df[,2:3], 2, function(x) x) 看到此转换为字符。
  • 很高兴知道!我最近根深蒂固地认为,尽可能避免使用 for 循环(它们曾经是我的支持),并且一直在尝试使用其他方法来提高效率。现在我知道应用函数可能不是最好的方法...... :)
  • for 循环可能是最快的方法之一,具体取决于您在做什么。在循环中增长对象是大多数人在早期犯的最大错误,应该避免。
【解决方案2】:

我会先将指标转换为以 H、L、M 为级别的因子,以确保所有 table 都指向 3 个类别。

这导致:

df=data.frame(Col1=paste0('row',1:15),metric1=sample(c('H','M','L'),15,replace = 1),metric2=sample(c('H','M'),15,replace = 1))
for (i in 2:ncol(df)){
  df[[i]] <- factor(df[[i]],levels=c("H","M","L"))
}

然后在每个列和堆栈上调用应用表:

sapply(df[-1],table)
      metric1 metric2
H       3       8
M       1       7
L      11       0

【讨论】:

    【解决方案3】:

    或者,您可以执行以下操作:

    sumer <- function(data, pattern)
    {
            temp <- colSums(sapply(pattern, grepl, data))
            names(temp) <- pattern
            temp
    }
    
    
    apply(df[, 2:3], 2, sumer, unique(df[, 2]))
    

    【讨论】:

      猜你喜欢
      • 2021-07-28
      • 1970-01-01
      • 1970-01-01
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-20
      相关资源
      最近更新 更多