【问题标题】:iterative computation ./ mutate of the mean of a large dataset within dplyr functions迭代计算 ./ dplyr 函数中大型数据集均值的变异
【发布时间】:2020-05-23 15:49:30
【问题描述】:

假设这是我的数据集

我想计算一个新变量(mutate),考虑到相同的模式(例如,lf_aparc_volume 和 rh_aparc_volune;然后是 lh_bankssts 和 rh_bankssts)。因此,新变量需要是一列的平均值,前面有 2 个空格,以此类推。 [在真实数据集中,我们在两列之间有 30 列我想取平均值]。

在excel中,选中两个变量后,会向右“拖拽”。因此,当结果“丢失”时,算法应该停止。

我想留在 tidyverse 环境中。 有什么建议吗?

编辑答案(感谢 Ian Campbell) 如果有人遇到同样的情况,请看下面的代码:

ds %>% #get the dataset
  pivot_longer(-identificacao, names_to = "variable", values_to = "values") %>% #re-arrange the way we see the ds
  separate(variable, into = c("group","variable"),
           sep = "_", extra = "merge") %>%  #fix names
  pivot_wider(id_cols = c("identificacao","group"),
              names_from = "variable", values_from = "values") %>% #wide format
  group_by(identificacao) %>% #now I'll group the take the means
  mutate(mean_aparc = mean(aparc_volume)) %>% 
  mutate(mean_bankssts = mean(bankssts_volume)) %>% 
  distinct(identificacao, .keep_all = TRUE) #keep only one identification per row

代码:

ds <-structure(list(identificacao = c("3004U", "77584X", "25917G", 
                                      "39895C", "20597Y", "64085M", "51573F", "42221E", "58658E", "8983C", 
                                      "18516K", "27050E"), lh_aparc_volume = c(2112, 2081, 2050, 2350, 
                                                                               2250, 1730, 1874, 1821, 2004, 1928, 1844, 2900), lh_bankssts_volume = c(1750, 
                                                                                                                                                       1654, 1344, 1876, 1366, 1424, 1416, 1521, 1231, 2415, 938, 1356
                                                                               ), rh_aparc_volume = c(1797, 1895, 1386, 1875, 2123, 1457, 1754, 
                                                                                                      2478, 1670, 1613, 1702, 1873), rh_bankssts_volume = c(1951, 1991, 
                                                                                                                                                            1774, 2539, 1830, 2564, 2433, 1092, 1803, 2009, 1609, 1787)), row.names = c(NA, 
                                                                                                                                                                                                                                        -12L), class = c("tbl_df", "tbl", "data.frame"))
ds

【问题讨论】:

    标签: r loops tidyverse dplyr


    【解决方案1】:

    这是bind_colsmap2 的方法:

    library(dplyr)
    library(purrr)
    cols.ahead <- 2
    ds %>%
    bind_cols(., map2(seq(2,ceiling(ncol(.)/2)),seq(2,ceiling(ncol(.)/2)) + cols.ahead,
                      ~ setNames((ds[,.x]+ds[,.y])/2,
                                 paste0(gsub(".+_(\\w+)_.+","\\1",names(ds)[.x]),"_mean"))))
    # A tibble: 12 x 7
       identificacao lh_aparc_volume lh_bankssts_volume rh_aparc_volume rh_bankssts_volume aparc_mean bankssts_mean
       <chr>                   <dbl>              <dbl>           <dbl>              <dbl>      <dbl>         <dbl>
     1 3004U                    2112               1750            1797               1951      1954.         1850.
     2 77584X                   2081               1654            1895               1991      1988          1822.
     3 25917G                   2050               1344            1386               1774      1718          1559 
     4 39895C                   2350               1876            1875               2539      2112.         2208.
     5 20597Y                   2250               1366            2123               1830      2186.         1598 
     6 64085M                   1730               1424            1457               2564      1594.         1994 
     7 51573F                   1874               1416            1754               2433      1814          1924.
     8 42221E                   1821               1521            2478               1092      2150.         1306.
     9 58658E                   2004               1231            1670               1803      1837          1517 
    10 8983C                    1928               2415            1613               2009      1770.         2212 
    11 18516K                   1844                938            1702               1609      1773          1274.
    12 27050E                   2900               1356            1873               1787      2386.         1572.
    

    另一种“tidyverse”方法是tidyr:pivot_longer

    library(dplyr)
    library(tidyr)
    ds %>%
      pivot_longer(-identificacao, names_to = "variable", values_to = "values") %>%
      separate(variable, into = c("group","variable"),
               sep = "_", extra = "drop") %>%
      pivot_wider(id_cols = c("identificacao","variable"),
                  names_from = "group", values_from = "values") %>%
      mutate(mean = (lh + rh)/2) %>%
      pivot_wider(id_cols = "identificacao",
                  names_from = "variable", 
                  values_from = c("lh","rh","mean"))
    
    # A tibble: 12 x 7
       identificacao lh_aparc lh_bankssts rh_aparc rh_bankssts mean_aparc mean_bankssts
       <chr>            <dbl>       <dbl>    <dbl>       <dbl>      <dbl>         <dbl>
     1 3004U             2112        1750     1797        1951      1954.         1850.
     2 77584X            2081        1654     1895        1991      1988          1822.
     3 25917G            2050        1344     1386        1774      1718          1559 
     4 39895C            2350        1876     1875        2539      2112.         2208.
     5 20597Y            2250        1366     2123        1830      2186.         1598 
     6 64085M            1730        1424     1457        2564      1594.         1994 
     7 51573F            1874        1416     1754        2433      1814          1924.
     8 42221E            1821        1521     2478        1092      2150.         1306.
     9 58658E            2004        1231     1670        1803      1837          1517 
    10 8983C             1928        2415     1613        2009      1770.         2212 
    11 18516K            1844         938     1702        1609      1773          1274.
    12 27050E            2900        1356     1873        1787      2386.         1572.
    

    显然,这会将 lhrh 移动到列名的末尾。如果这是破坏交易,您可以使用rename_at

    【讨论】:

    • 谢谢。使用您的第一个代码,我看到我们快到了。 ds %>% pivot_longer(-identificacao, names_to = "variable", values_to = "values") %>% 分离(变量, into = c("group","variable"), sep = "_", extra = "合并") %>% pivot_wider(id_cols = c("identificacao","group"), names_from = "variable", values_from = "values") %>% mutate(mean = (aparc_volume + bankssts_volume)/2) #aparc_volume 和 bankssts_volume 的平均值。换句话说,现在我们需要用 (2112 +1797)/2 计算一个新变量;然后 (2081+1895)/2 以此类推。
    • 谢谢。我不够清楚!我正在尝试自己更改您的代码,但如果可能的话,您能否给我一些建议以更改此特定部分?我正在尝试类似:group_by(group) %&gt;% mutate(mean_aparc = mean(aparc_volume)) %&gt;% mutate(mean_banksts = mean(bankssts_volume)) 但它不起作用。
    • 当然可以,但我可以使用您的代码并从一开始就做我想做的事。请看一下,非常感谢。 ds %&gt;% pivot_longer(-identificacao, names_to = "variable", values_to = "values") %&gt;% separate(variable, into = c("group","variable"), sep = "_", extra = "merge") %&gt;% pivot_wider(id_cols = c("identificacao","group"), names_from = "variable", values_from = "values") %&gt;% group_by(identificacao) %&gt;% mutate(mean_aparc = mean(aparc_volume)) %&gt;% mutate(mean_bankssts = mean(bankssts_volume)) %&gt;% distinct(identificacao, .keep_all = TRUE)
    • @Luis 我重新阅读了你的问题,我认为这可能是你要找的?
    【解决方案2】:

    简单的变异有什么问题?

    View(ds %>% mutate(col1 = (lh_aparc_volume + rh_aparc_volume) /2 ,col2 = (lh_bankssts_volume + rh_bankssts_volume)/2))
    

    【讨论】:

    • 您需要定义缺失值的行为
    • 感谢您的建议。实际上,这就是我想要的行为,但我想自动执行此操作,而不是输入所有变量名。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-07
    • 2014-04-01
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多