从具有选择条件的一个中提取多个 data.frames
Extract multiple data.frames from one with selection criteria
假设这是我的数据集:
df <- data.frame(x1 = runif(1000), x2 = runif(1000), x3 = runif(1000),
split = sample( c('SPLITMEHERE', 'OBS'), 1000, replace=TRUE, prob=c(0.04, 0.96) ))
所以,我有一些变量(在我的例子中是 15),以及我想将 data.frame 分成多个 data.frame 的标准。
我的标准如下:每次出现 'SPLITMEHERE' 我想获取所有值,或低于它的所有 'OBS' 并从这些观察中得到 data.frame .所以,如果开始 data.frame 有 20 'SPLITMEHERE's,我希望最后有 10 data.frames。
我知道这听起来令人困惑并且没有多大意义,但这是从非常脏的 .txt 文件中提取原始数字以获得有意义的数据的结果。基本上每个'SPLITMEHERE'表示这个.txt文件中的新table,但是每个县分为两个table,所以我想要一个table(data.frame) 每个县。
希望我能说得更清楚,这里是我需要的例子。假设前 20 个观察结果是:
x1 x2 x3 split
1 0.307379064 0.400526799 0.2898194543 SPLITMEHERE
2 0.465236674 0.915204924 0.5168274657 OBS
3 0.063814420 0.110380201 0.9564822116 OBS
4 0.401881416 0.581895095 0.9443995396 OBS
5 0.495227871 0.054014926 0.9059893533 SPLITMEHERE
6 0.091463620 0.945452614 0.9677482590 OBS
7 0.876123151 0.702328031 0.9739113525 OBS
8 0.413120761 0.441159673 0.4725571219 OBS
9 0.117764512 0.390644966 0.3511555807 OBS
10 0.576699384 0.416279417 0.8961428872 OBS
11 0.854786077 0.164332814 0.1609375612 OBS
12 0.336853841 0.794020157 0.0647337821 SPLITMEHERE
13 0.122690541 0.700047133 0.9701538396 OBS
14 0.733926139 0.785366852 0.8938749305 OBS
15 0.520766503 0.616765349 0.5136788010 OBS
16 0.628549288 0.027319848 0.4509875809 OBS
17 0.944188977 0.913900539 0.3767973795 OBS
18 0.723421337 0.446724318 0.0925365961 OBS
19 0.758001243 0.530991725 0.3916394396 SPLITMEHERE
20 0.888036748 0.862066601 0.6501050976 OBS
我想得到的是:
data.frame1:
1 0.465236674 0.915204924 0.5168274657 OBS
2 0.063814420 0.110380201 0.9564822116 OBS
3 0.401881416 0.581895095 0.9443995396 OBS
4 0.091463620 0.945452614 0.9677482590 OBS
5 0.876123151 0.702328031 0.9739113525 OBS
6 0.413120761 0.441159673 0.4725571219 OBS
7 0.117764512 0.390644966 0.3511555807 OBS
8 0.576699384 0.416279417 0.8961428872 OBS
9 0.854786077 0.164332814 0.1609375612 OBS
和
data.frame2:
1 0.122690541 0.700047133 0.9701538396 OBS
2 0.733926139 0.785366852 0.8938749305 OBS
3 0.520766503 0.616765349 0.5136788010 OBS
4 0.628549288 0.027319848 0.4509875809 OBS
5 0.944188977 0.913900539 0.3767973795 OBS
6 0.723421337 0.446724318 0.0925365961 OBS
7 0.888036748 0.862066601 0.6501050976 OBS
因此,拆分列只是告诉我拆分的位置,写入'SPLITMEHERE'的列中的数据是没有意义的。但是,这并不麻烦,因为我可以稍后删除这些行,重点是根据这个标准分隔多个 data.frames。
显然,split()
函数和 dplyr
中的 filter()
在这里是不够的。真正的问题是应该分隔 data.frame 的行(即每隔一个 'SPLITMEHERE')不会以常规方式出现,但就像我上面的例子一样。一旦有 3 行的间隙,其他时候可能是 10 或 15 行。
有什么方法可以在 R 中有效地提取它吗?
问题中最难的部分是创建组。一旦我们进行了适当的分组,就可以很容易地使用 split
来获得结果。
话虽如此,您可以对群组使用 cumsum
。在这里,我将 cumsum
除以 2 并使用 ceiling
,这样任何 2 SPLITMEHERE
的组都将折叠成一个。我还使用 ifelse
来排除 SPLITMEHERE
:
的行
df$group <- ifelse(df$split != "SPLITMEHERE", ceiling(cumsum(df$split=="SPLITMEHERE")/2), 0)
res <- split(df, df$group)
结果是一个列表,其中每个 group
都有一个数据框。带有 0
的组是您要删除的组。
假设这是我的数据集:
df <- data.frame(x1 = runif(1000), x2 = runif(1000), x3 = runif(1000),
split = sample( c('SPLITMEHERE', 'OBS'), 1000, replace=TRUE, prob=c(0.04, 0.96) ))
所以,我有一些变量(在我的例子中是 15),以及我想将 data.frame 分成多个 data.frame 的标准。
我的标准如下:每次出现 'SPLITMEHERE' 我想获取所有值,或低于它的所有 'OBS' 并从这些观察中得到 data.frame .所以,如果开始 data.frame 有 20 'SPLITMEHERE's,我希望最后有 10 data.frames。
我知道这听起来令人困惑并且没有多大意义,但这是从非常脏的 .txt 文件中提取原始数字以获得有意义的数据的结果。基本上每个'SPLITMEHERE'表示这个.txt文件中的新table,但是每个县分为两个table,所以我想要一个table(data.frame) 每个县。
希望我能说得更清楚,这里是我需要的例子。假设前 20 个观察结果是:
x1 x2 x3 split
1 0.307379064 0.400526799 0.2898194543 SPLITMEHERE
2 0.465236674 0.915204924 0.5168274657 OBS
3 0.063814420 0.110380201 0.9564822116 OBS
4 0.401881416 0.581895095 0.9443995396 OBS
5 0.495227871 0.054014926 0.9059893533 SPLITMEHERE
6 0.091463620 0.945452614 0.9677482590 OBS
7 0.876123151 0.702328031 0.9739113525 OBS
8 0.413120761 0.441159673 0.4725571219 OBS
9 0.117764512 0.390644966 0.3511555807 OBS
10 0.576699384 0.416279417 0.8961428872 OBS
11 0.854786077 0.164332814 0.1609375612 OBS
12 0.336853841 0.794020157 0.0647337821 SPLITMEHERE
13 0.122690541 0.700047133 0.9701538396 OBS
14 0.733926139 0.785366852 0.8938749305 OBS
15 0.520766503 0.616765349 0.5136788010 OBS
16 0.628549288 0.027319848 0.4509875809 OBS
17 0.944188977 0.913900539 0.3767973795 OBS
18 0.723421337 0.446724318 0.0925365961 OBS
19 0.758001243 0.530991725 0.3916394396 SPLITMEHERE
20 0.888036748 0.862066601 0.6501050976 OBS
我想得到的是:
data.frame1:
1 0.465236674 0.915204924 0.5168274657 OBS
2 0.063814420 0.110380201 0.9564822116 OBS
3 0.401881416 0.581895095 0.9443995396 OBS
4 0.091463620 0.945452614 0.9677482590 OBS
5 0.876123151 0.702328031 0.9739113525 OBS
6 0.413120761 0.441159673 0.4725571219 OBS
7 0.117764512 0.390644966 0.3511555807 OBS
8 0.576699384 0.416279417 0.8961428872 OBS
9 0.854786077 0.164332814 0.1609375612 OBS
和
data.frame2:
1 0.122690541 0.700047133 0.9701538396 OBS
2 0.733926139 0.785366852 0.8938749305 OBS
3 0.520766503 0.616765349 0.5136788010 OBS
4 0.628549288 0.027319848 0.4509875809 OBS
5 0.944188977 0.913900539 0.3767973795 OBS
6 0.723421337 0.446724318 0.0925365961 OBS
7 0.888036748 0.862066601 0.6501050976 OBS
因此,拆分列只是告诉我拆分的位置,写入'SPLITMEHERE'的列中的数据是没有意义的。但是,这并不麻烦,因为我可以稍后删除这些行,重点是根据这个标准分隔多个 data.frames。
显然,split()
函数和 dplyr
中的 filter()
在这里是不够的。真正的问题是应该分隔 data.frame 的行(即每隔一个 'SPLITMEHERE')不会以常规方式出现,但就像我上面的例子一样。一旦有 3 行的间隙,其他时候可能是 10 或 15 行。
有什么方法可以在 R 中有效地提取它吗?
问题中最难的部分是创建组。一旦我们进行了适当的分组,就可以很容易地使用 split
来获得结果。
话虽如此,您可以对群组使用 cumsum
。在这里,我将 cumsum
除以 2 并使用 ceiling
,这样任何 2 SPLITMEHERE
的组都将折叠成一个。我还使用 ifelse
来排除 SPLITMEHERE
:
df$group <- ifelse(df$split != "SPLITMEHERE", ceiling(cumsum(df$split=="SPLITMEHERE")/2), 0)
res <- split(df, df$group)
结果是一个列表,其中每个 group
都有一个数据框。带有 0
的组是您要删除的组。