dplyr:在进行范围过滤时添加限定列名(“filter_all”,...)

时间:2017-08-10 07:43:29

标签: r dplyr purrr

我有一个非常广泛的&长数据集,我需要从中选择任何选择的变量满足特定条件的行。到目前为止,dplyr中的范围过滤和any_vars非常接近我的需要。举例说明:

x <- tibble(v1 = c(1, 1, 5, 3, 4), v2 = c(3, 1, 2, 1, 2))
filter_all(x, any_vars( . == min(.)))

产生

# A tibble: 3 x 2
     v1    v2
  <dbl> <dbl>
1     1   3
2     1   1
3     3   1

我想将“过滤变量”的名称添加到结果行中,如下所示:

     v1    v2   var
  <dbl> <dbl> <chr>
1     1   3    v1
2     1   1    v1
3     1   1    v2
4     3   1    v2

有什么建议吗?我怀疑map中的purrr函数之一可以逐个进行过滤,然后将结果组合起来。

当一个人有资格获得多个变量时(感谢@Moody_Mudskipper),我想多次显示该行 - 在这种情况下都是v1v2

3 个答案:

答案 0 :(得分:2)

你要去,这应该扩展到一个宽数据集。

var moment = require('moment');
Vue.use(moment)

避免构建大临时表:

x <- tibble(v1 = c(1, 1, 5, 3, 4), v2 = c(3, 1, 2, 1, 2))

library(dplyr)
library(tidyr)
x %>%
  mutate_all(rank,ties.method ="min") %>%
  gather(var,val) %>%
  cbind(x,.) %>%
  filter(val ==1) %>%
  select(-val)

#   v1 v2 var
# 1  1  3  v1
# 2  1  1  v1
# 3  1  1  v2
# 4  3  1  v2

这是更加丑陋的,但我认为这是我能提出的最有效的方法:

gathered <- x %>%
  mutate_all(rank,ties.method ="min") %>%
  gather(var,val)
rows_to_keep <- which(gathered$val == 1)
cbind(x[(rows_to_keep-1) %% nrow(x) + 1,],gathered[rows_to_keep,])

答案 1 :(得分:0)

试试这段代码:

XmlSerializerNamespaces

如果有帮助,请告诉我们。谢谢。

此代码在一个条件下将失败:如果一行中有多个变量是最小值。例如,在发布的示例中,如果有一行同时包含1,那么此代码将失败。谢谢

答案 2 :(得分:0)

感谢您创建新列的想法,我的解决方案首先在过滤之前存储变量名称。如果你能改进这一点,请告诉我:

x %>%  
  mutate_all(funs(qual = . == min(.))) %>%
  filter_at(vars(ends_with("_qual")), any_vars(. == TRUE)) %>%
  gather(var, qual, ends_with("_qual")) %>%
  filter(qual==TRUE) %>%
  select(-qual) %>%
  extract(var, "var")

第一步之后的中间表:

     v1    v2 v1_qual v2_qual
1     1     3    TRUE   FALSE
2     1     1    TRUE    TRUE
3     5     2   FALSE   FALSE
4     3     1   FALSE    TRUE
5     4     2   FALSE   FALSE