【问题标题】:Filtering rows by different columns按不同列过滤行
【发布时间】:2021-03-10 05:10:57
【问题描述】:

在数据框中

  x1 x2 x3 x4 x5
1  0  1  1  0  3
2  1  2  2  0  3
3  2  2  0  0  2
4  1  3  0  0  2
5  3  3  2  1  4
6  2  0  0  0  1

column x5 表示一行中第一个非零值的位置。该表应从右 (x4) 到左 (x1) 阅读。因此,例如,第一行中的第一个非零值在 x3 列中。

我想获取第一个非零条目为 1 的所有行,即

  x1 x2 x3 x4 x5
1  0  1  1  0  3
2  3  3  2  1  4

应该是结果。我尝试了不同版本的 filter_at 但我没有想出一个解决方案。例如。一次尝试是

testdf %>% filter_at(vars(
    paste("x",testdf$x5, sep = "")),
    any_vars(. == 1))

我想在没有 for 循环的情况下解决这个问题,因为真实的数据集有数百万行和近 100 列。

【问题讨论】:

  • 我不明白?在您的 df 第一行中,x2 不为零,那么为什么 x5 说 3?在第 2 行中,x1 不为零,那为什么 x5 也说 3?
  • 您必须从右 (x4) 到左 (x1) 读取它。抱歉,我忘了提。

标签: r filter dplyr tidyverse


【解决方案1】:

您可以使用新的实用函数 c_across 轻松进行逐行过滤:

library(dplyr) # version 1.0.2

testdf %>% rowwise() %>% filter(c_across(x1:x4)[x5] == 1) %>% ungroup()
# A tibble: 2 x 5
     x1    x2    x3    x4    x5
  <int> <int> <int> <int> <int>
1     0     1     1     0     3
2     3     3     2     1     4

【讨论】:

  • 感谢您的解决方案!不幸的是,我的 dplyr 版本太旧(没有 c_across 函数),我无法更新它,因为它不是我的私有 R 版本。否则,您的答案将被接受(因为它是第一个)。
【解决方案2】:

矢量化的基础 R 解决方案是:

result <- df[df[cbind(1:nrow(df), df$x5)] == 1, ]
result

#  x1 x2 x3 x4 x5
#1  0  1  1  0  3
#5  3  3  2  1  4

cbind(1:nrow(df), df$x5) 在每一行中创建一个最大值的行列矩阵。我们提取这些第一个值并选择其中包含 1 的行。

【讨论】:

    【解决方案3】:

    另一个矢量化解决方案:

    df[t(df)[t(col(df)==df$x5)]==1,]
    

    【讨论】:

      【解决方案4】:

      我们可以在base R中使用apply

      df1[apply(df1, 1, function(x) x[x[5]] == 1),]
      #  x1 x2 x3 x4 x5
      #1  0  1  1  0  3
      #5  3  3  2  1  4
      

      数据

      df1 <- structure(list(x1 = c(0L, 1L, 2L, 1L, 3L, 2L), x2 = c(1L, 2L, 
      2L, 3L, 3L, 0L), x3 = c(1L, 2L, 0L, 0L, 2L, 0L), x4 = c(0L, 0L, 
      0L, 0L, 1L, 0L), x5 = c(3L, 3L, 2L, 2L, 4L, 1L)), 
      class = "data.frame", row.names = c("1", 
      "2", "3", "4", "5", "6"))
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-01-10
        • 1970-01-01
        • 2019-07-30
        • 2013-08-17
        • 1970-01-01
        • 2016-08-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多