根据组中的所有行是否具有特定值来拆分数据框

MAJ*_*MAJ 5 split r dataframe

我有一个像这样的数据框:

df <- data.frame(x = c(0,0,1,1,2,2,3,3,4,4,5,5), y = c(0,1,1,1,0,0,0,1,1,1,0,0))
Run Code Online (Sandbox Code Playgroud)

如何将数据拆分为两个数据框,其中每个x值的两个y值都等于 1?

df
   x y
1  0 0
2  0 1
3  1 1 # x = 1: all y = 1
4  1 1 #
5  2 0
6  2 0
7  3 0
8  3 1
9  4 1 # x = 4: all y = 1
10 4 1 #
11 5 0
12 5 0
Run Code Online (Sandbox Code Playgroud)

两个结果数据框将如下所示:

df1 <- data.frame(x = c(1,1,4,4), y = c(1,1,1,1))
df1
  x y
1 1 1
2 1 1
3 4 1
4 4 1

df2 <- data.frame(x = c(0,0,2,2,3,3,5,5), y = c(0,1,0,0,0,1,0,0))
df2
  x y
1 0 0
2 0 1
3 2 0
4 2 0
5 3 0
6 3 1
7 5 0
8 5 0
Run Code Online (Sandbox Code Playgroud)

Ony*_*mbu 7

在基数 R 中:

split(df, ~ave(y == 1, x, FUN = all))
$`FALSE`
   x y
1  0 0
2  0 1
5  2 0
6  2 0
7  3 0
8  3 1
11 5 0
12 5 0

$`TRUE`
   x y
3  1 1
4  1 1
9  4 1
10 4 1
Run Code Online (Sandbox Code Playgroud)

在 tidyverse 中:

library(tidyverse)
df %>%
  group_by(x) %>%
  mutate(s = all(y==1))%>%
  ungroup() %>%
  group_split(s, .keep = FALSE)

[[1]]
# A tibble: 8 x 2
      x     y
  <dbl> <dbl>
1     0     0
2     0     1
3     2     0
4     2     0
5     3     0
6     3     1
7     5     0
8     5     0

[[2]]
# A tibble: 4 x 2
      x     y
  <dbl> <dbl>
1     1     1
2     1     1
3     4     1
4     4     1
Run Code Online (Sandbox Code Playgroud)


das*_*sh2 1

因此:

library(dplyr)
df <- df |> group_by(x) |> mutate(all_y_1 = all(y==1)) 

df1 <- df |> filter(all_y_1) |> select(-all_y_1)
df2 <- df |> filter(! all_y_1) |> select(-all_y_1)
Run Code Online (Sandbox Code Playgroud)