【问题标题】:R subset data.frame columns by group to maximize row valuesR子集data.frame列按组最大化行值
【发布时间】:2015-02-07 02:42:16
【问题描述】:

我有一个与这里描述的非常相似的问题:

subset of data.frame columns to maximize "complete" observations

我正在尝试安排一个将举行五次会议的研讨会。我有十天的时间来选择会议日期,每天有三个重叠的可能会议时间。因此,我将 30 列分为十组(天),每组三列(会议时间)。我需要根据以下条件选择 5 列(或会议日期-时间组合):每天只选择一个会议时间(每组一列);可以参加所有 5 次会议的受访者(行)的数量最大化。理想情况下,如果我放宽受访者必须参加所有 5 次会议的标准,只要求他们参加 4 次或 3 次等,我还想知道最佳列选择如何变化。

对于简单的可视化,假设我想知道我应该选择哪两列 - V1、V2 和 V3 中的每一个不超过一个 - 这样我就可以最大化不为零的行数(即行总和为2)。

V1A   V1B   V1C   V2A   V2B   V2C   V3A   V3B   V3C  
1     0     1     0     1     1     1     0     1   
1     1     0     0     1     1     0     1     1   
0     0     1     1     1     0     0     1     1   
1     1     1     1     0     0     1     0     0 
1     0     0     0     1     1     0     1     0 
0     1     1     0     1     1     0     0     0 
1     0     1     1     1     0     1     0     1

实际数据在这里:https://drive.google.com/file/d/0B03dE9-8088aMklOUVhuV3gtRHc/view 组是 mon1* tue1* [...] mon2* tue2* [...] fri2*。

如果我不需要从组中选择列,上面链接中建议的代码将解决我的问题。理想情况下,我还可以说明在行可能有一个零的较弱条件下(即行总和为 5 或 4 或 3 等),我应该选择哪些列以最大化行数。

非常感谢!

【问题讨论】:

    标签: r subset maximization


    【解决方案1】:

    您可以使用rowSums 来获取大于或等于两个 1 的行的索引。 (条件不是很清楚)

      lapply(split(names(df),sub('.$', '', names(df))), 
              function(x) which(rowSums(df[x])>=2))
      #$V1
      #[1] 1 2 4 6 7
    
      #$V2
      #[1] 1 2 3 5 6 7
    
      #$V3
      #[1] 1 2 3 7
    

    【讨论】:

      【解决方案2】:

      这只是在三组中的每一组中找到第一列索引为 1(或第一个,如果全为零),返回一个三列矩阵,每组一列。

      f <- substring(colnames(df), 1L, nchar(colnames(df))-1L)
      ans <- lapply(split(as.list(df), f),
                    function(x) max.col(do.call(cbind, x), ties.method="first"))
      do.call(cbind, ans)
      

      【讨论】:

        【解决方案3】:

        使用您的数据集,这会交付满足交付所有行的要求的行==1:

        > lapply( 1:3, function(grp) which( apply( dat[, grep(grp, names(dat))] , 1, 
                                                   function(z) sum(z, na.rm=TRUE)==3) ) )
        [[1]]
        [1] 4
        
        [[2]]
        integer(0)
        
        [[3]]
        integer(0)
        

        如果您放宽要求,允许值小于 3,您将获得更多候选人:

        > lapply( 1:3, function(grp) which( apply( dat[, grep(grp, names(dat))] , 1, function(z) sum(z, na.rm=TRUE)>=2) ) )
        [[1]]
        [1] 1 2 4 6 7
        
        [[2]]
        [1] 1 2 3 5 6 7
        
        [[3]]
        [1] 1 2 3 7
        

        现在,,,,,,, 这个任务的具体规则是什么??????

        【讨论】:

          猜你喜欢
          • 2014-07-23
          • 2011-10-19
          • 2016-06-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-04-30
          • 2015-06-17
          相关资源
          最近更新 更多