【问题标题】:R Create new data frame for each unique idR为每个唯一ID创建新数据框
【发布时间】:2013-09-06 00:06:08
【问题描述】:

我创建了一个特征向量(data.frame),它有一个 id、feat1、feat2、feat3、boolean,但是在这个数据框中有重复的 id,这是有目的的。我想要做的是在迭代这个数据框时为每个 id 构建新的数据框。

为简单起见,假设我有以下两列。

          X1         X2      X3
1   000000001 -1.4061361     1
2   000000001 -0.1973846     1
3   000000002 -0.4385071     1
4   000000001 -0.6593677     0
5   000000001 -1.2592415     0
6   000000001 -0.5463655     1
7   000000002  0.4231117     0
8   000000002 -0.1640883     1
9   000000002  0.7157506     0
10  000000002  2.3234110     1

我想基于 X1 构建不同的数据框基本上我想将所有相同的 X1 放入自己的数据框。我使用多个 for 循环编写,但由于这是一个大型数据集,因此需要很长时间。最好的方法是什么?

【问题讨论】:

  • 请注意,创建所有这些副本至少会使您的内存使用量翻倍。因此,如果您打算对每个块进行一些分析并仅保存一小部分摘要结果,请查看函数 by()
  • @Ferdinand.kraft 是的,我计划进行分析,事实上我这样做的原因是我想在每个上运行随机森林,所以我实际上担心内存消耗。您如何建议我在这种情况下使用 by?
  • @find-missing-semicolon 抱歉,我不使用随机森林...但是by() 接受任何适用于数据帧块并返回汇总数据的函数。

标签: r dataframe


【解决方案1】:

按照 cmets 中的建议,使用 split。如果您真的想创建新对象,请将splitlist2env 结合使用,如下所示:

## What is in the workspace presently?
ls()
# [1] "mydf"

## This is where most R users would probably stop
split(mydf, mydf$X1)
# $`1`
#   X1         X2 X3
# 1  1 -1.4061361  1
# 2  1 -0.1973846  1
# 4  1 -0.6593677  0
# 5  1 -1.2592415  0
# 6  1 -0.5463655  1
# 
# $`2`
#    X1         X2 X3
# 3   2 -0.4385071  1
# 7   2  0.4231117  0
# 8   2 -0.1640883  1
# 9   2  0.7157506  0
# 10  2  2.3234110  1

上面的命令创建了一个list,如果你要对每个列表项进行类似的计算,这是一种非常方便的格式。大多数 R 用户会停在那里。如果你真的需要在你的工作空间中单独的对象,使用list2env:

list2env(split(mydf, mydf$X1), envir=.GlobalEnv)
# <environment: R_GlobalEnv>

## How many objects do we have now?
ls()
# [1] "1"    "2"    "mydf"

请注意,这些名称在语法上无效,因此您需要使用反引号(&lt;/code&gt;) to access them. (Or, alternatively,get("1")`).

`1`
# X1 X2 X3
# 1 1 -1.4061361 1
# 2 1 -0.1973846 1
# 4 1 -0.6593677 0
# 5 1 -1.2592415 0
# 6 1 -0.5463655 1
`2`
# X1 X2 X3
# 3 2 -0.4385071 1
# 7 2 0.4231117 0
# 8 2 -0.1640883 1
# 9 2 0.7157506 0
# 10 2 2.3234110 1

【讨论】:

    【解决方案2】:

    这使用一个 for 循环 - 更好?

    ids <- unique(df$X1)
    
    for(i in 1:length(ids)){
        id <- ids[i]
        mini.df <- data.frame(df[df$X1 == id, ])
        assign(paste("mini.df", i, sep="."), mini.df)
        # or alternatively, if you wanted the data.frames to be assigned by id, 
        # assign(id, mini.df)
    }
    

    【讨论】:

      【解决方案3】:

      听起来您希望能够将模型拟合到每个数据子集(并可能提取模型的摘要)。您可以使用 broom、dplyr、purrr 和 tidyr 在功能上执行此操作。这是一个例子:

      library(broom)
      library(dplyr)
      library(purrr)
      library(tidyr)
      
      mtcars %>%
        group_by(cyl) %>%
        nest() %>%
        mutate(model = map(data, lm, formula = mpg ~ disp + hp),
               results = map(model, tidy)) %>%
        unnest(results)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-14
        • 1970-01-01
        • 1970-01-01
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        • 2015-08-23
        • 2019-01-20
        相关资源
        最近更新 更多