【问题标题】:How to make calculations with specific rows with purrr nested data如何使用 purrr 嵌套数据对特定行进行计算
【发布时间】:2020-07-21 19:37:57
【问题描述】:

所以我刚开始使用 Purrr 和嵌套数据,我很喜欢它,但我也有点迷茫。

我的列表看起来有点像:

library(tidyverse)

test <- tibble(
  id= rep(1:3, each=20),
  Index = rep(1:20, 3),
  x = rnorm(60),
  y = rnorm(60),
  z = rnorm(60)
)

id  Index    x         y        z
1     1     0.03     -0.39     0.4
1     2     1.2      -0.49     0.6
1     3     1.6      -0.59     0.7
....
2     1     0.2      -6.2      0.1
2     2     1.1      -6.3      0.6
2     3     1.5      -5.1      0.4
...

我通过 id 嵌套了数据

t_nest <- test %>% group_by(id) %>% nest()

+--------------------+----------------------+-----+--+---+
| # A tibble: 3 x 2  |                      |     |  |   |
+--------------------+----------------------+-----+--+---+
| # Groups:   id [3] |                      |     |  |   |
|                    |  id data             |     |  |   |
|   <int> <list>     |                      |     |  |   |
| 1                  |  1 <tibble [20 x 4]> |     |  |   |
| 2                  |  2 <tibble [20 x 4]> |     |  |   |
| 3                  |  3 <tibble [20 x 4]> |     |  |   |
+--------------------+----------------------+-----+--+---+

所以我现在要做的是计算每组的第一个和第二个索引之间的 x 差。我通过改变一个只包含前两个索引行的新列来解决这个问题。比我取消嵌套该列并进行计算并再次删除它。

inlever <- function(x){
  inlever = abs(x[[1]]-x[[2]])
  return(inlever)
}

test_inlever <- t_nest %>% 
  mutate(inlever_coord = map(data, ~filter(.,Index == c("1","2")))) %>%  unnest(inlever_coord) %>% 
  group_by(id) %>% 
  mutate(inlever_d = inlever(x)) %>% 
  select(-c(x,y,z,Index))


+--------------------+----------------------+--------+--+-------------+
| # A tibble: 6 x 3  |                      |        |  |             |
+--------------------+----------------------+--------+--+-------------+
| # Groups:   id [3] |                      |        |  |             |
|                    |  id data             |inlever |  |             |
|   <int> <list>     |                      |  <dbl> |  |             |
| 1                  |  1 <tibble [20 x 4]> |  1.68  |  |             |
| 2                  |  1 <tibble [20 x 4]> |  1.68  |  |             |
| 3                  |  2 <tibble [20 x 4]> |  0.964 |  |             |
| 4                  |  2 <tibble [20 x 4]> |  0.964 |  |             |
| 5                  |  3 <tibble [20 x 4]> |  0.135 |  |             |
| 6                  |  3 <tibble [20 x 4]> |  0.135 |  |             |
+--------------------+----------------------+--------+--+-------------+


我现在的问题是

  1. 有更简单的方法吗?我可以通过只选择我想要使用的两行来直接在嵌套数据中计算吗?
  2. 有没有办法重命名嵌套表中的数据部分?而不是“数据”,我希望它被称为“坐标”,如下所示:
+--------------------+----------------------+-----+--+---+
| # A tibble: 3 x 2  |                      |     |  |   |
+--------------------+----------------------+-----+--+---+
| # Groups:   id [3] |                      |     |  |   |
|                    |  id coordinates      |     |  |   |
|   <int> <list>     |                      |     |  |   |
| 1                  |  1 <tibble [20 x 4]> |     |  |   |
| 2                  |  2 <tibble [20 x 4]> |     |  |   |
| 3                  |  3 <tibble [20 x 4]> |     |  |   |
+--------------------+----------------------+-----+--+---+

【问题讨论】:

    标签: r tidyverse tidyr purrr


    【解决方案1】:

    这就是你要找的吗?只需三行代码,使用直接来自原始数据帧的匿名函数即可轻松完成。我们首先排列数据,以便我们知道索引的顺序正确,将其嵌套(使用您的新名称),然后进行变异以进行计算。

    
    test %>%
      arrange(id, Index) %>%
      nest(coordinates = -id) %>%
      mutate(inlever_d = map_dbl(coordinates, ~ abs(.x[['x']][1] - .x[['x']][2])))
    #> # A tibble: 3 x 3
    #>      id coordinates       inlever_d
    #>   <int> <list>                <dbl>
    #> 1     1 <tibble [20 x 4]>     0.330
    #> 2     2 <tibble [20 x 4]>     0.850
    #> 3     3 <tibble [20 x 4]>     0.487
    

    【讨论】:

    • 这是完美的。太感谢了。我尝试了类似的方法,但我不知道如何调用嵌套数据框中的特定单元格。
    【解决方案2】:

    我会在嵌套数据之前单独进行inlever 计算,如果我们需要数据,然后通过连接将其添加到结果中。

    library(dplyr)
    
    test %>%
      filter(Index %in% c(1, 2)) %>%
      group_by(id) %>%
      summarise(inlever_d = inlever(x)) %>%
      left_join(test %>% tidyr::nest(coordinates = -id), by = 'id')
    
    
    # A tibble: 3 x 3
    #     id inlever_d coordinates      
    #  <int>     <dbl> <list>           
    #1     1     0.330 <tibble [20 × 4]>
    #2     2     0.850 <tibble [20 × 4]>
    #3     3     0.487 <tibble [20 × 4]>
    

    数据

    set.seed(123)
    test <- tibble(
              id= rep(1:3, each=20),
              Index = rep(1:20, 3),
              x = rnorm(60),
              y = rnorm(60),
              z = rnorm(60)
              )
    

    【讨论】:

    • 哦,这是一个很好的解决方案。我想我对嵌套部分有点着迷,因为我还必须做很多其他计算。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-06-29
    • 2023-03-19
    • 1970-01-01
    • 2018-03-08
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多