【问题标题】:Count number of occurrences of several column cases计算几个列案例的出现次数
【发布时间】:2020-12-09 22:45:35
【问题描述】:

我有一个数据框:

ID   Date            col1  col2  
1    1606807860      LOY    A
2    1606807860      LOY    B
2    1606807860      LOY    B
3    1606807860      LOY    B
1    1606807860      LOY    A

我想根据 ID、Date、col1 和 col2 计算唯一值的出现次数。所以,想要的结果是:

ID     Date              event    count
1    1606807860          loy-a      2
2    1606807860          loy-b      2
3    1606807860          loy-b      1

我怎么能这样做?另外如何将时间戳格式转换为正常格式,而不是 1606807860?如何更改日期类型?把它变成年月日?

这适用于只有 col1 和 col2 的情况:

%>%
  mutate(across(c(col1, col2), tolower)) %>%
  count(col1, col2) %>%
  unite(event, col1, col2, sep='-')

【问题讨论】:

    标签: r dataframe count


    【解决方案1】:

    在这种情况下,我们不是一一指定多个列,而是在group_by 中使用across,然后从namessummarise 中指定一个列范围

    library(dplyr)
    library(stringr)
    df1 %>%
       group_by(across(names(.)[1:4])) %>%
       summarise(count = n(), .groups = 'drop') %>%
       mutate(event = tolower(str_c(col1, col2, sep="-"))) %>%
       select(-col1, -col2)
    

    -输出

    # A tibble: 3 x 4
    #     ID       Date count event
    #  <int>      <int> <int> <chr>
    #1     1 1606807860     2 loy-a
    #2     2 1606807860     2 loy-b
    #3     3 1606807860     1 loy-b
    

    或者我们可以创建group_by

    df1 %>% 
       group_by(across(ID:Date), event = tolower(str_c(col1, col2, sep='-'))) %>%
       summarise(count = n(), .groups = 'drop') %>%
       mutate(Date = as.Date(as.POSIXct(Date, origin = '1970-01-01')))
    

    -输出

    # A tibble: 3 x 4
    #     ID Date       event count
    #  <int> <date>     <chr> <int>
    #1     1 2020-12-01 loy-a     2
    #2     2 2020-12-01 loy-b     2
    #3     3 2020-12-01 loy-b     1
    

    或者countunite

    library(tidyr)
    df1 %>%
       mutate(across(c(col1, col2), tolower)) %>%
       unite(event, col1, col2, sep='-') %>%
       count(ID, Date, event)
    

    -输出

    #   ID       Date event n
    #1  1 1606807860 loy-a 2
    #2  2 1606807860 loy-b 2
    #3  3 1606807860 loy-b 1
    

    数据

    df1 <- structure(list(ID = c(1L, 2L, 2L, 3L, 1L), Date = c(1606807860L, 
    1606807860L, 1606807860L, 1606807860L, 1606807860L), col1 = c("LOY", 
    "LOY", "LOY", "LOY", "LOY"), col2 = c("A", "B", "B", "B", "A"
    )), class = "data.frame", row.names = c(NA, -5L))
    

    【讨论】:

    • 以及如何更改日期类型?让它像年月日?
    • @french_fries 该数字列的预期日期是什么
    • @french_fries 你可能需要as.Date(as.POSIXct(df1$Date, origin = '1970-01-01'))
    • @french_fries 请检查我的更新。谢谢
    • @french_fries 如果您检查代码,我会先更新帖子
    【解决方案2】:

    试试这个:

    library(dplyr)
    #Code
    new <- df %>% group_by(ID,Date,event=tolower(paste0(col1,'-',col2))) %>%
      summarise(N=n()) %>% mutate(Date=as.Date(as.POSIXct(Date,origin = "1970-01-01")))
    

    输出:

    # A tibble: 3 x 4
    # Groups:   ID, Date [3]
         ID Date       event     N
      <int> <date>     <chr> <int>
    1     1 2020-12-01 loy-a     2
    2     2 2020-12-01 loy-b     2
    3     3 2020-12-01 loy-b     1
    

    【讨论】:

    • 以及如何更改日期类型?让它像年月日?
    • @french_fries 预期的日期输出是什么?
    • @french_fries 已更新,希望对您有所帮助!
    【解决方案3】:

    基本 R 选项

    aggregate(
      n ~ .,
      transform(
        df,
        event = tolower(paste(col1, col2, sep = "-")),
        Date = as.Date(as.POSIXct(Date, origin = "1970-01-01")),
        n = 1,
        col1 = NULL,
        col2 = NULL
      ),
      sum
    )
    

    给了

      ID       Date event n
    1  1 2020-12-01 loy-a 2
    2  2 2020-12-01 loy-b 2
    3  3 2020-12-01 loy-b 1
    

    data.table 选项

    setDT(df)
    df[, Date := as.Date(as.POSIXct(Date, origin = "1970-01-01"))][, .(event = tolower(paste(col1, col2, sep = "-")), n = .N), by = names(df)][, c("col1", "col2") := NULL][]
    

    给了

       ID       Date event n
    1:  1 2020-12-01 loy-a 2
    2:  2 2020-12-01 loy-b 2
    3:  3 2020-12-01 loy-b 1
    

    数据

    > dput(df)
    structure(list(ID = c(1L, 2L, 2L, 3L, 1L), Date = c(1606807860L,
    1606807860L, 1606807860L, 1606807860L, 1606807860L), col1 = c("LOY",
    "LOY", "LOY", "LOY", "LOY"), col2 = c("A", "B", "B", "B", "A"
    )), class = "data.frame", row.names = c(NA, -5L))
    

    【讨论】:

    • @akrun 感谢您的提醒!我相应地调整了我的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-23
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多