Nano Hash - криптовалюты, майнинг, программирование

подведение итогов data.table - создание нескольких подмножеств столбцов по дате в R

У меня есть данные о ID и соответствующем amount за несколько лет. Что-то вроде этого:

 ID <- c(rep("A", 5), rep("B", 7), rep("C", 3))
  amount <- c(sample(1:10000, 15))
  Date <- c("2016-01-22","2016-07-25", "2016-09-22", "2017-10-22", "2017-01-02",
              "2016-08-22", "2016-09-22", "2016-10-22", "2017-08-22", "2017-09-22", "2017-10-22", "2018-08-22", 
              "2016-10-22","2017-10-25", "2018-10-22")

Теперь я хочу проанализировать каждый год каждого ID. В частности, меня интересует amount. Во-первых, я хочу знать общую сумму за каждый год. Затем я также хочу узнать общую сумму за первые 11 месяцев каждого года, первые 10 месяцев каждого года, первые 9 месяцев каждого года и первые 8 месяцев каждого года. Для этой цели я рассчитал cumSum за каждые ID за year следующим образом:

  myData <- cbind(ID, amount, Date)
  myData <- as.data.table(myData)

  # createe cumsum per ID per Year
  myData$Date <- as.Date(myData$Date, format = "%Y-%m-%d")
  myData[order(clientID, clDate)]
  myData[, CumSum := cumsum(amount), by =.(ID, year(Date))]

Как суммировать data.table так, чтобы я получал столбцы amount9month, amount10month, amount11month для каждого идентификатора в каждом году?

24.05.2020

Ответы:


1

Между cumsum, by и dcast это почти довольно просто. Самое сложное — это иметь дело с теми месяцами, когда нет данных. Следовательно, это решение не такое краткое, как могло бы быть, но оно делает вещи «способом data.table» и позволяет избежать медленных операций, таких как циклическое перебор строк.

# Just sort the formatting out first
myData[, Date:=as.Date(Date)]
myData[, `:=`(amount = as.numeric(amount),
              year = year(Date),
              month = month(Date))]
bycols <- c('ID', 'year', 'month')

# Summarise all transactions for the same ID in the same month
summary <- myData[, .(amt = sum(amount)), by=bycols]

# Create a skeleton table with all possible combinations of ID, year and month, to fill in any gaps.
skeleton <- myData[, CJ(ID, year, month = 1:12, unique = TRUE)]

# Join the skeleton to the actual data, to recreate the data but with no gaps in
result.long <- summary[skeleton, on=bycols, allow.cartesian=TRUE]
result.long[, amt.cum:=cumsum(fcoalesce(amt, 0)), by=c('ID', 'year')]

# Cast the data into wide format to have one column per month
result.wide <- dcast(result.long, ID + year ~ paste0('amount',month,'month'), value.var='amt.cum')

Примечание. Если у вас нет fcoalesce, обновите пакет data.table.

24.05.2020
  • Отличный момент - спасибо! Я отредактировал свой ответ, чтобы отразить это. 25.05.2020

  • 2

    В каком формате вы хотите? Есть два простых варианта. Вы можете легко получить запрошенный результат в двух разных форматах:

    # Prepare the data
    ID <- c(rep("A", 5), rep("B", 7), rep("C", 3))
    amount <- c(sample(1:1, 15, replace = TRUE))
    Date <- c("2016-01-22","2016-07-25", "2016-09-22", "2017-10-22", "2017-01-02", "2016-08-22", "2016-09-22", "2016-10-22", "2017-08-22", "2017-09-22", "2017-10-22", "2018-08-22", "2016-10-22","2017-10-25", "2018-10-22")
    myData <- data.frame(ID, amount, Date)
    # Add year column
    myData$Date <- as.Date(myData$Date, format = "%Y-%m-%d")
    myData$year <- format(myData$Date,"%Y")
    

    Обратите внимание, что я изменил amount в целях тестирования. Теперь два решения.

    # Format 1
    by(myData$amount, list(myData$ID, myData$year), cumsum, simplify = TRUE)
    # Format 2
    aggregate(myData$amount, list(ID = myData$ID, Date = myData$year), cumsum)
    

    Однако вы можете захотеть, чтобы результатом был новый столбец во фрейме данных? Вы можете решить это:

    # Format: New column
    myData <- myData[order(myData$year, myData$ID),] # sort by year and ID
    myData$cumsum <- rep(0, nrow(myData))
    for (r in 1:nrow(myData)) {
      if (r > 1 && myData$year[r-1] == myData$year[r] && myData$ID[r-1] == myData$ID[r])
        myData$cumsum[r] <- myData$cumsum[r-1] + myData$amount[r]
      else
        myData$cumsum[r] <- myData$amount[r]
    }
    

    Я не знаю гладкого решения с базовым R. Может быть, у кого-то из "фракции дплр" есть хитрый трюк в рукаве?

    24.05.2020
  • Думаешь, мне лучше удалить его? 24.05.2020
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..