我正在尝试使用 dplyr 过滤数据框,但我真的想不出一种方法来实现我想要的。我有一个以下形式的数据框:
A B C
-----------
1 2 5
1 4 6
2 2 7
2 4 6
Run Code Online (Sandbox Code Playgroud)
列中的每个值A恰好出现 2 次。ColumnB恰好有 2 个不同的值,每个值对于 的每个值都恰好出现一次A。列C可以具有任何正值。我想保留所有行,其中对于一个值A,具有较大值的行B具有C比具有较小值的行更小的值B。在上面的示例中,这将导致:
A B C
-----------
2 2 7
2 4 6
Run Code Online (Sandbox Code Playgroud)
有没有办法使用 dplyr 来实现这一目标?
1)按 A 和 B 排序,以确保较大的 B 始终是 A 中的第二个,然后按 A 分组,使用基于 diff(C) < 0 的过滤器。
\nlibrary(dplyr)\n\nDF %>%\n arrange(A, B) %>%\n group_by(A) %>%\n filter((diff(C) < 0)) %>%\n ungroup\n## # A tibble: 2 \xc3\x97 3\n## A B C\n## <int> <int> <int>\n## 1 2 2 7\n## 2 2 4 6\nRun Code Online (Sandbox Code Playgroud)\n2)另一种可能性是确保 B 的最大值与 C 的最小值位于同一行。这也适用于非数字数据。
\n请参阅此答案下面的评论,了解类似的另一个想法。
\nDF %>%\n group_by(A) %>%\n filter(which.max(B) == which.min(C)) %>%\n ungroup\nRun Code Online (Sandbox Code Playgroud)\n3)如果 B 相对于 C 的斜率为负,则保留该组。
\nDF %>%\n group_by(A) %>%\n filter(coef(lm(B ~ C))[[2]] < 0) %>%\n ungroup\nRun Code Online (Sandbox Code Playgroud)\n或者我们可以自己计算斜率:
\nDF %>%\n group_by(A) %>%\n filter(diff(C) / diff(B) < 0) %>%\n ungroup\nRun Code Online (Sandbox Code Playgroud)\nLines <- "A B C\n1 2 5\n1 4 6\n2 2 7\n2 4 6"\n\nDF <- read.table(text = Lines, header = TRUE)\nRun Code Online (Sandbox Code Playgroud)\n