Как сделать расчеты с указанными c строками с мурлыкающими вложенными данными - PullRequest
2 голосов
/ 09 апреля 2020

Итак, я только начал работать с 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]> |     |  |   |
+--------------------+----------------------+-----+--+---+

Так что я теперь хочу сделать это рассчитать разницу х между первым и вторым индексом каждой группы. Я работал над этим, мутируя новый столбец с только строками для первых двух индексов. Затем я удалил этот столбец, произвел расчет и снова удалил его.

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]> |     |  |   |
+--------------------+----------------------+-----+--+---+

Ответы [ 2 ]

2 голосов
/ 09 апреля 2020

Это то, что вы ищете? Это легко сделать всего за три строки кода с помощью анонимной функции прямо из исходного фрейма данных. Сначала мы упорядочиваем данные, чтобы знать, что индексы находятся в правильном порядке, вкладываем их (с вашим новым именем) и изменяем в один для выполнения вычислений.


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
1 голос
/ 09 апреля 2020

Я бы сделал вычисление 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)
          )
...