【问题标题】:Extract multiple data.frames from one with selection criteria从一个具有选择标准的数据帧中提取多个数据帧
【发布时间】:2017-05-08 14:29:51
【问题描述】:

让这成为我的数据集:

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.frames 的标准。

我的标准如下:每次出现“SPLITMEHERE”时,我都想获取所有值,或者它下面的所有“OBS”,并从这些观察中获取一个data.frame。所以,如果在开始的 data.frame 中有 20 个“SPLITMEHERE”,我想最终得到 10 个 data.frame。

我知道这听起来令人困惑,而且似乎没有多大意义,但这是从一个非常脏的 .txt 文件中提取原始数字以获取有意义的数据的结果。基本上,每个 'SPLITMEHERE' 都表示这个 .txt 文件中的新表,但是每个县分为两个表,所以我想要每个县一个表(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() 函数和来自dplyrfilter() 在这里是不够的。真正的问题是应该分隔data.frames的行(即每隔一个'SPLITMEHERE')不会以常规方式出现,但就像我上面的例子一样。一旦有 3 行的间隙,其他时候可能是 10 或 15 行。

有没有办法在 R 中有效地提取它?

【问题讨论】:

    标签: r select dataframe data-manipulation


    【解决方案1】:

    问题中最困难的部分是创建组。一旦我们有了正确的分组,就很容易使用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 的组是您要丢弃的组。

    【讨论】:

    • 谢谢,这正是我需要的!
    • 现在我注意到了这个数据的另一个特点。即,第四个县仅包含一个表,这意味着该县的group 应该在第一个 SPLITMEHERE 结束,而不是第二个。此外,最后一个县由三个表组成,但这并不重要,因为它在最后,所以我可以轻松地合并最后一组。有什么想法吗?
    • 当您的组只有 1 个 splitmehere 时,也许使用 rep 将除以 2 更改为除以 1?没有数据很难说 - 你应该考虑发布一个新问题
    • 谢谢,我先玩一会儿,看看我能做什么。
    • 很遗憾我没有成功。这是后续问题:stackoverflow.com/questions/44021913/…
    猜你喜欢
    • 2021-03-22
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 1970-01-01
    • 1970-01-01
    • 2020-07-01
    • 1970-01-01
    • 2021-01-09
    相关资源
    最近更新 更多