【问题标题】:for loop to print frequency table when freq > 3当freq > 3时for循环打印频率表
【发布时间】:2016-12-23 22:36:10
【问题描述】:

在下面的例子中,我希望扫描B 的每一行,如果它们出现超过3 次,则只删除一次。我尝试了以下 for 循环,但还没有成功。

set.seed(123456)

B = matrix( sample(1:100, 100, replace = T), 
            nrow=10,
            ncol=10)

for(i=1:nrow(B)){
  which(table(B[i,])>3){
    NA
  }
  print(i)
}

所需的输出是每行中适当值的列表

【问题讨论】:

  • 示例已更改,因此可以找到更一致的答案

标签: r for-loop


【解决方案1】:

你可以这样做:

apply(B, 1, function(x) as.numeric(names(table(x)[which(table(x) > 3)])))

或者,根据 ProcrastinatusMaximus 的评论,一个较短的版本:

apply(B, 1, function(x) as.integer(names(which(table(x) > 3))))

【讨论】:

  • 这里不需要which。你可以做apply(B,1,function(x) as.numeric(names(table(x)>3)))
  • 我不同意,names() 将选择所有名称,而不管 T/F 状态如何。我们必须只选择符合条件的那些。例如:as.numeric(names(table(c(1,1,1,1,2,2,2))>3)) 在应该返回 1 时返回 1 和 2。
  • 我的立场是正确的。我被identical(apply(B,1,function(x) as.numeric(names(table(x)>3))), apply(B,1,function(x) as.numeric(names(table(x)[which(table(x)>3)]))))误导了
  • 短一点:apply(B, 1, function(x) as.integer(names(which(table(x) > 3))))
【解决方案2】:

这不会将其保留在每一行中,但可能值得研究使用的包 (matrixStats)

library(matrixStats)
as.numeric(colnames(rowTabulates(B)>3))

【讨论】:

    【解决方案3】:

    这是一个使用data.table 的选项。使用 melt from 'data.table' 转换为 'long' 格式,转换为 'data.table' (setDT(...)),按 'Var1', 'value' 分组,我们只得到 if 的频率计数计数大于 3。

    library(data.table)
    setDT(melt(B))[, if(.N > 3) .N, .(Var1, value)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多