1

我在一个简单的问题上遇到了麻烦,我找不到简单的解决方案。(这个问题可能是一个duplicate但我找不到它!)

我需要的是merge在计算后将列表支持到其原始列表。

我需要这样做,merge因为我正在做的计算对apply他们来说太复杂了,直接列出来了。所以,我必须分开做,并以某种方式将它放回原始数据集。mutate(因为这个问题, 我这里不能直接使用)。

因为我无法重现我的数据,所以我将用它mtcars来演示我的问题。

我有一个原始列表,我正在对其应用计算(哪个都没有关系),例如:

library(dplyr) 
library(purr) 

我的原始数据集是一个列表

dt = mtcars %>% 
  group_by(gear) %>% 
  split(.$gear)

然后,在这个列表中,我做一个计算,例如:

dt %>% 
  map(~summarise(., cluster = mean(disp)))

我最终得到一个list.

我的数据的(真实)结构最终看起来像这样

$`3`
   gear cluster
1     3   326.3

$`4`
    gear cluster
 1     4   123

等等。我需要的只是将merge back这个列表改为原始列表。我怎样才能做到这一点 ?

我需要(想要的输出)最终得到(在这里很难重现)我的原始值listmerged计算值。

就像是

$`3`

     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb cluster 
1   21.4     6 258.0   110  3.08 3.215 19.44     1     0     3     1  XXX
2   18.7     8 360.0   175  3.15 3.440 17.02     0     0     3     2  XXX
3   18.1     6 225.0   105  2.76 3.460 20.22     1     0     3     1  XXX
4   14.3     8 360.0   245  3.21 3.570 15.84     0     0     3     4  XXX

等等所有列表(df)

我再次强调,我的原始数据集是 list 而不是 data.frame。我需要的是合并lists,而不是data.frame

我想到了类似的东西

dt = mtcars %>% # my data is a list
  group_by(gear) %>% 
  split(.$gear)

fmerge = function(x) x %>% lapply(dt, ., by = 'gear')

dt %>% 
  map(~summarise(., cluster = mean(disp))) %>% 
  lapply(fmerge) 

或者

dt %>% 
  map(~summarise(., cluster = mean(disp))) %>% 
  join_all(dt, ., by = 'gear')

但效果不好。

有什么线索吗?

4

3 回答 3

2

我们可以使用bind_rowsrbindlist元素然后执行right_joinorleft_join

mtcars %>% 
   group_by(gear) %>% 
   split(.$gear) %>% 
   map(~summarise(., cluster = mean(disp))) %>%
   bind_rows() %>%
   right_join(., mtcars, by = "gear")

但是,这可以通过在我们“齿轮”之后split/map/bind_rows/right_join创建“集群”来完成mutategroup_by

mtcars %>% 
     group_by(gear) %>%
     mutate(cluster = mean(disp))

但是,我们假设这个简化的过程可能不适用于 OP 的原始数据集。

更新

根据 OP 的评论,我们可以map2使用left_joinlist

dt %>%
    map(~summarise(., cluster = mean(disp))) %>% 
    map2(dt, ., left_join, by = "gear")

或者如果我们需要一个data.frame,那么使用map2df

dt %>%
    map(~summarise(., cluster = mean(disp))) %>% 
    map2_df(dt, ., left_join, by = "gear")
于 2016-09-05T11:11:14.763 回答
1

可能的解决方案,但速度慢,因为loop

将计算存储在“列表”中

computation = dt %>% map(~summarise(., cluster = mean(disp)))

然后遍历两者list

for(i in 1:length(dt)){
  dt[[i]] = merge(dt[[i]], computation[[i]], by = 'gear')
}

要得到

$`3`
   gear  mpg cyl  disp  hp drat    wt  qsec vs am carb cluster
1     3 21.4   6 258.0 110 3.08 3.215 19.44  1  0    1   326.3
2     3 18.7   8 360.0 175 3.15 3.440 17.02  0  0    2   326.3
3     3 18.1   6 225.0 105 2.76 3.460 20.22  1  0    1   326.3

等等。

于 2016-09-05T12:34:41.470 回答
0

我会利用nest()tidyr 包(然后unnest()是 )中可以做的有趣的事情,如下所示:

library(tidyr)
library(dplyr)
library(purrr)

mtcars %>% 
  nest(-gear) %>% 
  mutate(cluster = map_dbl(data, ~ mean(.$disp))) %>% 
  unnest(data)
#> # A tibble: 32 × 12
#>     gear  cluster   mpg   cyl  disp    hp  drat    wt  qsec    vs    am
#>    <dbl>    <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1      4 123.0167  21.0     6 160.0   110  3.90 2.620 16.46     0     1
#> 2      4 123.0167  21.0     6 160.0   110  3.90 2.875 17.02     0     1
#> 3      4 123.0167  22.8     4 108.0    93  3.85 2.320 18.61     1     1
#> 4      4 123.0167  24.4     4 146.7    62  3.69 3.190 20.00     1     0
#> 5      4 123.0167  22.8     4 140.8    95  3.92 3.150 22.90     1     0
#> 6      4 123.0167  19.2     6 167.6   123  3.92 3.440 18.30     1     0
#> 7      4 123.0167  17.8     6 167.6   123  3.92 3.440 18.90     1     0
#> 8      4 123.0167  32.4     4  78.7    66  4.08 2.200 19.47     1     1
#> 9      4 123.0167  30.4     4  75.7    52  4.93 1.615 18.52     1     1
#> 10     4 123.0167  33.9     4  71.1    65  4.22 1.835 19.90     1     1
#> # ... with 22 more rows, and 1 more variables: carb <dbl>

如果您运行此管道的前两行,然后是三行,您将看到有一列数据集对应于数据中的组。这使您可以做一些非常复杂的事情,而无需将数据拆分为单独的列表。

例如,下面对每个齿轮的数据进行回归分析(同样,尝试运行前 2 条,然后 3 条等管道线以了解其工作原理),然后绘制结果:

library(broom)
library(ggplot2)

mtcars %>% 
  nest(-gear) %>% 
  mutate(fits = map(data, ~ lm(mpg ~ hp, .)),
         predicted = map(fits, augment)) %>% 
  unnest(predicted) %>% 
  ggplot(aes(mpg, .fitted)) +
    geom_point() +
    facet_grid(. ~ gear)

在此处输入图像描述

于 2016-09-05T11:32:45.363 回答