【问题标题】:How to combine transmute with grep function?如何将 transmute 与 grep 函数结合起来?
【发布时间】:2020-08-10 15:26:19
【问题描述】:

我正在尝试找到一种方法,使用现有数据框中的 rowSums() 函数创建一个包含变量的新表。例如,我现有的数据框称为'asn',我想总结变量标题中包含“2011”的所有变量的每一行的值。我想要一个只包含一个名为asn_y2011 的列的新表,其中包含使用包含“2011”的变量的每一行的总和

数据

structure(list(row = 1:3, south_2010 = c(1L, 5L, 7L), south_2011 = c(4L, 
0L, 4L), south_2012 = c(5L, 8L, 6L), north_2010 = c(3L, 4L, 1L
), north_2011 = c(2L, 6L, 0L), north_2012 = c(1L, 1L, 2L)), class = "data.frame", row.names = c(NA, 
-3L))

现有的'asn' 数据框如下所示

row south_2010 south_2011 south_2012 north_2010 north_2011 north_2012
  1      1           4         5          3          2          1
  2      5           0         8          4          6          1
  3      7           4         6          1          0          2

我正在尝试使用以下功能:

asn %>%   
   transmute(asn_y2011 = rowSums(, grep("2011")))

得到这样的东西

row    asn_y2011
 1         6
 2         6
 3         4

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    继续使用您的代码,grep() 应该像这样工作:

    library(dplyr)
    
    asn %>%
      transmute(row, asn_y2011 = rowSums(.[grep("2011", names(.))]))
    
    #   row asn_y2011
    # 1   1         6
    # 2   2         6
    # 3   3         4
    

    或者你可以在c_across()中使用整洁的选择

    asn %>%
      rowwise() %>% 
      transmute(row, asn_y2011 = sum(c_across(contains("2011")))) %>%
      ungroup()
    

    【讨论】:

      【解决方案2】:

      另一个使用rowSums的基本R选项

      cbind(asn[1],asn_y2011 = rowSums(asn[grep("2011",names(asn))]))
      

      给了

        row asn_y2011
      1   1         6
      2   2         6
      3   3         4
      

      【讨论】:

        【解决方案3】:

        base R 中带有Reduce 的选项

        cbind(df['row'], asn_y2011 = Reduce(`+`, df[endsWith(names(df), '2011')]))
        #  row asn_y2011
        #1   1         6
        #2   2         6
        #3   3         4
        

        数据

        df <- structure(list(row = 1:3, south_2010 = c(1L, 5L, 7L), south_2011 = c(4L, 
        0L, 4L), south_2012 = c(5L, 8L, 6L), north_2010 = c(3L, 4L, 1L
        ), north_2011 = c(2L, 6L, 0L), north_2012 = c(1L, 1L, 2L)), 
        class = "data.frame", row.names = c(NA, 
        -3L))
        

        【讨论】:

          【解决方案4】:

          我认为这段代码会做你想做的事:

          library(magrittr)
          tibble::tibble(row = 1:3, south_2011 = c(4, 0, 4), north_2011 = c(2, 6, 0)) %>%
            tidyr::gather(- row, key = "key", value = "value") %>%
            dplyr::mutate(year = purrr::map_chr(.x = key, .f = function(x)stringr::str_split(x, pattern = "_")[[1]][2])) %>%
            dplyr::group_by(row, year) %>%
            dplyr::summarise(sum(value))
          

          我首先加载包magrittr,这样我就可以使用管道%&gt;%。我已经明确列出了导出函数的包,但如果你愿意,欢迎使用library 加载包。

          然后我创建一个 tibble 或数据框,就像您指定的那样。

          在创建新变量year 之前,我使用gather 重新组织数据框。然后我按rowyear 的值汇总计数。

          【讨论】:

          • pivot_longer 是替代gather 的新改进功能。更强大、更直观。
          【解决方案5】:

          你可以试试这个方法

          library(tidyverse)
          df2 <- df %>% 
            select(grep("_2011|row", names(df), value = TRUE)) %>% 
            rowwise() %>% 
            mutate(asn_y2011 = sum(c_across(south_2011:north_2011))) %>% 
            select(row, asn_y2011)
            
          #     row asn_y2011
          #   <int>     <int>
          # 1     1         6
          # 2     2         6
          # 3     3         4
          

          数据

          df <- structure(list(row = 1:3, south_2010 = c(1L, 5L, 7L), south_2011 = c(4L, 0L, 4L), south_2012 = c(5L, 8L, 6L), north_2010 = c(3L, 4L, 1L), north_2011 = c(2L, 6L, 0L), north_2012 = c(1L, 1L, 2L)), class = "data.frame", row.names = c(NA,-3L))
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-06-13
            • 2021-09-06
            • 1970-01-01
            • 2021-08-06
            • 2013-10-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多