比较多列是否相等

an_*_*ade 1 equality r startswith filter tidyverse

这可能是使用dplyr和tidyverse 工具的一个非常基本的问题,但我找不到一个好的方法来做到这一点。

\n

假设我有一个宽格式的数据框,并且我想选择行,以便列的子集具有所有相同的值。天真地,我可以执行以下操作:

\n
> df <- tribble(\n    ~name, ~id,  ~cost, ~value1 , ~value2, ~value3,\n    "a",     1,     10,       1,        1,       1,\n    "a",     2,     20,       1,        2,       1,\n    "b",     3,     50,       1,        1,       3,\n    "b",     4,     45,       1,        1,       1,\n    "b",     5,     70,       2,        2,       2\n)\n\n\n> df %>% select(\n    value1 == value2 &\n    value1 == value3 &\n    value2 == value\n)\n\n# A tibble: 3 \xc3\x97 6\n  name     id  cost value1 value2 value3\n  <chr> <dbl> <dbl>  <dbl>  <dbl>  <dbl>\n1 a         1    10      1      1      1\n2 b         4    45      1      1      1\n3 b         5    70      2      2      2\n
Run Code Online (Sandbox Code Playgroud)\n

现在,假设要比较的列数非常大(> 10)。所有列都以 开头value,因此我们可能有value_something, value_otherthing, value_morething,即不一定像本例中那样是数字。但是,如果列数为n,我必须天真地创建n * (n - 1) / 2比较,这显然是难以管理的。

\n

有没有类似的东西

\n
df %>% filter(all_same(starts_with("value")))\n
Run Code Online (Sandbox Code Playgroud)\n

where通过(或任何其他选择器)all_same()比较所有选定的列?starts_with()

\n

rowwise()并且\n across()\ndidn\也没有给我太多帮助。

\n

akr*_*run 5

我们可以使用if_all循环从“value2”到“value3”的列,检查列值是否等于value1,if_all仅对于所有列比较都为 TRUE 的行返回 TRUE

\n
library(dplyr)\ndf %>%\n    filter(if_all(value2:value3, ~ value1 == .x))\n
Run Code Online (Sandbox Code Playgroud)\n

-输出

\n
# A tibble: 3 \xc3\x97 6\n  name     id  cost value1 value2 value3\n  <chr> <dbl> <dbl>  <dbl>  <dbl>  <dbl>\n1 a         1    10      1      1      1\n2 b         4    45      1      1      1\n3 b         5    70      2      2      2\n
Run Code Online (Sandbox Code Playgroud)\n
\n

或者如果我们想使用starts_with

\n
df %>%\n    filter(if_all(starts_with('value'), ~ value1 == .x))\n
Run Code Online (Sandbox Code Playgroud)\n