【问题标题】:drop both row and column satisfying condition in symmetric dataframe在对称数据框中删除满足条件的行和列
【发布时间】:2020-01-01 21:23:09
【问题描述】:

设置

我的任务看起来类似于this one,但不完全一样。假设我有一个像这样的对称数据框

df <- data.frame(
    matrix(c(1, 7, 0, 5, 9, 0,
             7, 4, 0, 8, 2, 0, 
             0, 0, 0, 0, 0, 0, 
             5, 8, 0, 1, 1, 0, 
             9, 2, 0, 1, 1, 0, 
             0, 0, 0, 0, 0, 0), nrow=6, ncol=6)
)

看起来像这样

  X1 X2 X3 X4 X5 X6
1  1  7  0  5  9  0
2  7  4  0  8  2  0
3  0  0  0  0  0  0
4  5  8  0  1  1  0
5  9  2  0  1  1  0
6  0  0  0  0  0  0

因为如果一行全是零是对称的,具有相同索引的对应列也将全是零。

我想做什么

我想删除所有仅包含零的行和列(通常,我想删除所有满足某些条件的行和列)。理想情况下,我想在 tidyverse 中使用函数。如果我能以某种方式使用管道,那就太好了。

可以用管道做到这一点吗?

重要

我犯了一个错误,我认为该解决方案必须适用于稀疏矩阵。请问有可能有一个适用于dgCMatrix 类的实现吗? IE。对于稀疏矩阵?

当我尝试下面的许多 tidyverse 实现时,我得到了

Error in UseMethod("tbl_vars") : 
  no applicable method for 'tbl_vars' applied to an object of class "c('dgCMatrix', 'CsparseMatrix', 'dsparseMatrix', 'generalMatrix', 'dCsparseMatrix', 'dMatrix', 'sparseMatrix', 'compMatrix', 'Matrix', 'xMatrix', 'mMatrix', 'Mnumeric', 'replValueSp')"

【问题讨论】:

  • 基本 R 选项是 Filter(var, subset(df, rowSums(df!=0) &gt; 0))
  • @akrun 我将发布一个单独的问题,因为我犯了一个错误。我需要它来处理稀疏矩阵。你能帮忙吗?

标签: r dataframe subset tidyverse


【解决方案1】:

你可以这样做:

df %>%
 select_if(~ any(. != 0)) %>%
 filter_all(any_vars(. != 0))

  X1 X2 X4 X5
1  1  7  5  9
2  7  4  8  2
3  5  8  1  1
4  9  2  1  1

【讨论】:

  • ~ 是做什么的?
  • 我很困惑,所有这些功能似乎都在variables 上运行,等等列,但它们过滤掉了行?
  • 它被称为波浪号运算符。查看help("~") 和cran.r-project.org/web/packages/dplyr/vignettes/…。 select() 系列函数在列级别上运行,而filter() 系列在行上运行。所以在这种情况下,它首先删除所有值为零的列,然后删除所有值为零的所有行。
  • filter_all()中的一个参数是.vars_predicate,应该是A quoted predicate expression as returned by all_vars() or any_vars().。 dplyr 本质上不是矩阵的选择。
  • 我认为你应该问一个单独的问题(关于矩阵),因为这个问题已经有了答案。
【解决方案2】:

一个选项是组合来自tidyverse 的dplyr 和purrr 包

df %>%
  filter_all(any_vars(. != 0)) %>%
  purrr::keep(~all((.x != 0)))

  X1 X2 X4 X5
1  1  7  5  9
2  7  4  8  2
3  5  8  1  1
4  9  2  1  1

或使用Base R 检查每行和每列的标准差 (sd),因为 sd 的常数为 0。

df[apply(df, 1, sd) != 0, apply(df, 2, sd) != 0]

  X1 X2 X4 X5
1  1  7  5  9
2  7  4  8  2
4  5  8  1  1
5  9  2  1  1

【讨论】:

【解决方案3】:

在base R,我们可以做

Filter(var, subset(df, rowSums(df!=0) > 0))

【讨论】:

    【解决方案4】:

    有多种方法可以对数据框执行此操作。

    rowSums 和 colSums 的基本 R 选项可以是

    df[rowSums(df == 0) != ncol(df), colSums(df == 0) != nrow(df)]
    
    #  X1 X2 X4 X5
    #1  1  7  5  9
    #2  7  4  8  2
    #4  5  8  1  1
    #5  9  2  1  1
    

    【讨论】:

      猜你喜欢
      • 2013-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      • 2020-06-10
      • 2020-12-22
      相关资源
      最近更新 更多