【问题标题】:How to make a new column in a data.frame so that column counts the number of different row in that data.frame?如何在 data.frame 中创建一个新列,以便该列计算该 data.frame 中不同行的数量?
【发布时间】:2019-03-29 19:14:43
【问题描述】:

我有一个像这样的巨大 data.frame。

首先,如何在此 data.frame 中添加一个新列“date1”,以便该列计算此 data.frame 中 UNIQUE 不同日期的数量,然后在该新创建的列中按升序排列。

其次,如何在此 data.frame 中添加另一列“date2”,以便该列计算一天中不同 id 的总数?

    year  month day id
    2011    1   5   31
    2011    1   14  22
    2011    2   6   28
    2011    2   17  41
    2011    3   9   55
    2011    1   5   34
    2011    1   14  25
    2011    2   6   36
    2011    2   17  11
    2011    3   12  10

我期望的结果是这样的。请帮忙!

    year month day  id date1 date2
    2011    1   5   31  1     2
    2011    1   14  22  2     2
    2011    2   6   28  3     2
    2011    2   17  41  4     2
    2011    3   9   55  5     1
    2011    1   5   34  1     2
    2011    1   14  25  2     2
    2011    2   6   36  3     2
    2011    2   17  11  4     2
    2011    3   12  10  6     1

【问题讨论】:

    标签: r


    【解决方案1】:

    我们可以在tidyverse 中更紧凑地执行此操作,方法是在group_by 中获取“年”、“月”、“日”的group_indices,然后创建“日期2”作为不同元素的数量'id' (n_distinct)

    librarytidyverse)
    df1 %>% 
         group_by(date1 = group_indices(., year, month, day)) %>% 
         mutate(date2 = n_distinct(id))
    # A tibble: 10 x 6
    # Groups:   date1 [6]
    #    year month   day    id date1 date2
    #   <int> <int> <int> <int> <int> <int>
    # 1  2011     1     5    31     1     2
    # 2  2011     1    14    22     2     2
    # 3  2011     2     6    28     3     2
    # 4  2011     2    17    41     4     2
    # 5  2011     3     9    55     5     1
    # 6  2011     1     5    34     1     2
    # 7  2011     1    14    25     2     2
    # 8  2011     2     6    36     3     2
    # 9  2011     2    17    11     4     2
    #10  2011     3    12    10     6     1
    

    或者data.table 的另一个紧凑选项(使用相同的逻辑)

    library(data.table)
    setDT(df1)[, date1 := .GRP, .(year, month, day)][, date2 := uniqueN(id), date1][]
    #     year month day id date1 date2
    # 1: 2011     1   5 31     1     2
    # 2: 2011     1  14 22     2     2
    # 3: 2011     2   6 28     3     2
    # 4: 2011     2  17 41     4     2
    # 5: 2011     3   9 55     5     1
    # 6: 2011     1   5 34     1     2
    # 7: 2011     1  14 25     2     2
    # 8: 2011     2   6 36     3     2
    # 9: 2011     2  17 11     4     2
    #10: 2011     3  12 10     6     1
    

    或者这可以通过base R 中的interactionave 来完成

    df1$date1 <- with(df1, as.integer(interaction(year, month, day, 
             drop = TRUE, lex.order = TRUE)))
    df1$date2 <- with(df1, ave(id, date1, FUN = function(x) length(unique(x))))
    

    数据

    df1 <- structure(list(year = c(2011L, 2011L, 2011L, 2011L, 2011L, 2011L, 
    2011L, 2011L, 2011L, 2011L), month = c(1L, 1L, 2L, 2L, 3L, 1L, 
    1L, 2L, 2L, 3L), day = c(5L, 14L, 6L, 17L, 9L, 5L, 14L, 6L, 17L, 
    12L), id = c(31L, 22L, 28L, 41L, 55L, 34L, 25L, 36L, 11L, 10L
    )), class = "data.frame", row.names = c(NA, -10L))
    

    【讨论】:

      【解决方案2】:

      我们可以首先使用uniteyearmonthday组合成一列,并为该组合的每一组赋予一个唯一编号,然后group_by相同的组合并计算唯一的id对于每个组合使用n_distinct

      library(dplyr)
      library(tidyr)
      
      df %>%
        unite(date, year, month, day, sep = "-", remove = FALSE) %>%
        mutate(date1 = as.integer(factor(date,level = unique(date)))) %>%
        group_by(date) %>%
        mutate(date2 = n_distinct(id)) %>%
        ungroup() %>%
        select(-date)
      
      
      #    year month   day    id date1 date2
      #   <int> <int> <int> <int> <int> <int>
      # 1  2011     1     5    31     1     2
      # 2  2011     1    14    22     2     2
      # 3  2011     2     6    28     3     2
      # 4  2011     2    17    41     4     2
      # 5  2011     3     9    55     5     1
      # 6  2011     1     5    34     1     2
      # 7  2011     1    14    25     2     2
      # 8  2011     2     6    36     3     2
      # 9  2011     2    17    11     4     2
      #10  2011     3    12    10     6     1
      

      【讨论】:

      • 谢谢@Ronak Shah,我已经尝试过了,但 data1 列的结果与我的预期不符。我有 3 年的数据,数据的最后一天应该是新列中的最大数字,但事实并非如此。这是数据中的另一天。像这样的错误在这里和那里。 Date2 没问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多