【问题标题】:Count data divided by year and by region in R计数数据除以 R 中的年份和地区
【发布时间】:2019-04-20 18:20:50
【问题描述】:

我有一个非常大(在 Excel 中无法打开)的生物数据集,看起来像这样

    year <- c(1990, 1980, 1985, 1980, 1990, 1990, 1980, 1985, 1985,1990, 
              1980, 1985, 1980, 1990, 1990, 1980, 1985, 1985,
              1990, 1980, 1985, 1980, 1990, 1990, 1980, 1985, 1985)
    species <- c('A', 'A', 'B', 'B', 'B', 'C', 'C', 'C', 'A','A', 'A', 
                 'B', 'B', 'B', 'C', 'C', 'C', 'A', 'A', 'A', 'B', 'B', 'B', 
                 'C', 'C', 'C', 'A')
    region <- c(1, 1, 1, 3, 2, 3, 3, 2, 1, 1, 3, 3, 3, 2, 2, 1, 1, 1,1, 3, 3, 
                3, 2, 2, 1, 1, 1)
    df <- data.frame(year, species, region)

    df
    year species region
 1  1990       A      1
 2  1980       A      1
 3  1985       B      1
 4  1980       B      3
 5  1990       B      2
 6  1990       C      3
 7  1980       C      3
 8  1985       C      2
 9  1985       A      1
 10 1990       A      1
 11 1980       A      3
 12 1985       B      3
 13 1980       B      3
 14 1990       B      2
 15 1990       C      2
 16 1980       C      1
 17 1985       C      1
 18 1985       A      1
 19 1990       A      1
 20 1980       A      3
 21 1985       B      3
 22 1980       B      3
 23 1990       B      2
 24 1990       C      2
 25 1980       C      1
 26 1985       C      1
 27 1985       A      1

我要做的是弄清楚在我拥有的三年(1980 年、1985 年、1985 年、或 1990 年)。

我希望最终得到一个看起来与此类似的数据集,

      region A_1980 B_1980 C_1980 A_1985 B_1985 C_1985 A_1990 B_1990 C_1990
 1      1      0      0      0      0      0      0      0      0      0
 2      2      1      1      1      1      1      1      1      1      1
 3      3      2      2      2      2      2      2      2      2      2

每行代表一个地区,每列代表特定年份中每个物种的数量。我尝试使用spread 函数和group_by dplyr 函数来做到这一点,但我无法让它做任何接近我想要的事情。

有人有什么建议吗?

【问题讨论】:

    标签: r grouping tidyverse data-management


    【解决方案1】:

    这样的?

    library(dplyr)
    
    df2 <- df %>% 
      mutate(sp_year = paste(species, year, sep = "_")) %>%
      group_by(region) %>% 
      count(sp_year) %>% 
      spread(sp_year,n)
    
    df2
    

    这给出了这个:

    # A tibble: 3 x 10
    # Groups:   region [3]
      region A_1980 A_1985 A_1990 B_1980 B_1985 B_1990 C_1980 C_1985 C_1990
       <dbl>  <int>  <int>  <int>  <int>  <int>  <int>  <int>  <int>  <int>
    1      1      1      3      3     NA      1     NA      2      2     NA
    2      2     NA     NA     NA     NA     NA      3     NA      1      2
    3      3      2     NA     NA      3      2     NA      1     NA      1
    

    【讨论】:

    • 也可以使用?tidyr::unite 代替mutate(paste)。至少会不那么冗长。
    【解决方案2】:

    类似于 wl1234 的答案,但更简洁。我们可以使用unite 来组合列。我们也可以使用 count 而不使用 group_by 变量。最后,我们可以在spread函数中设置fill = 0,将NA替换为0。

    library(tidyverse)
    
    df2 <- df %>%
      unite(sp_year, species, year, sep = "_") %>%
      count(sp_year, region) %>%
      spread(sp_year, n, fill = 0)
    df2
    # # A tibble: 3 x 10
    #   region A_1980 A_1985 A_1990 B_1980 B_1985 B_1990 C_1980 C_1985 C_1990
    #    <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>  <dbl>
    # 1      1      1      3      3      0      1      0      2      2      0
    # 2      2      0      0      0      0      0      3      0      1      2
    # 3      3      2      0      0      3      2      0      1      0      1
    

    【讨论】:

    • 这太棒了,我也喜欢 NA => 0 加法!谢谢!
    • 我不知道unite。下次我将使用它而不是 paste
    猜你喜欢
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 2012-06-06
    • 2019-07-26
    • 2020-11-21
    • 1970-01-01
    • 2019-08-01
    • 2021-11-29
    相关资源
    最近更新 更多