Как считать условные счета и суммы?

Я хочу сделать что-то подобное COUNTIFS и SUMIFS в R, используя пакет data.table.

Вот мои данные.

library(data.table)
treesData<-as.data.table(trees)
bins<-seq(63, length.out = 10, by = 3);
aggtable <- data.table(bin1 = bins[-length(bins)], bin2 = bins[-1])

Вот чего я хочу достичь: Count - это счет по высоте, если он находится в интервале и Girth.total — это сумма по обхвату.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
89
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы можете использовать

cond <- expression(treesData$Height %between% .(bin1, bin2 - 1))

aggtable[, c("Count", "Girth.Total") := list(
  sum(eval(cond)),
  sum(treesData$Girth[eval(cond)])), by = .I]

#> aggtable
#    bin1  bin2 Count Girth.Total
#   <num> <num> <int>       <num>
#1:    63    66     3        31.2
#2:    66    69     1        11.0
#3:    69    72     3        33.7
#4:    72    75     4        53.9
#5:    75    78     6        73.3
#6:    78    81     7       104.5
#7:    81    84     4        56.3
#8:    84    87     2        26.2
#9:    87    90     1        20.6

Я думаю, что код можно встроить в сами квадратные скобки data.table, даже не используя eval и выражение.

Mohit 14.07.2024 18:04

Предложите использовать обозначение интервалов, чтобы было понятно, какие конечные точки включены, а какие исключены.

treesData[, bin := cut(Height, bins, right = FALSE)][,
  .(count = .N, tot = sum(Girth)), keyby = bin]

предоставление

Key: <bin>
       bin count   tot
    <fctr> <int> <num>
1: [63,66)     3  31.2
2: [66,69)     1  11.0
3: [69,72)     3  33.7
4: [72,75)     4  53.9
5: [75,78)     6  73.3
6: [78,81)     7 104.5
7: [81,84)     4  56.3
8: [84,87)     2  26.2
9: [87,90]     1  20.6

Примечание

Входы

library(data.table)

treesData<-as.data.table(trees)
bins<-seq(63, length.out = 10, by = 3)

Немного проще, группируем на лету: treesData[, .(count = .N, tot = sum(Girth)), keyby = .(bin = cut(Height, bins, right = FALSE)) ]

zx8754 15.07.2024 12:25

Спасибо, пожалуйста, могу ли я запросить еще два улучшения: 1) два столбца count и tot справа от data.table aggtable и 2) при запуске этого кода не отображаются выходные данные в консоли.

Mohit 15.07.2024 12:40

Если treeData[...][...] — это решение выше, измените его на DT <- treeData[...][...][, cbind(aggtable, .SD)].

G. Grothendieck 15.07.2024 14:40
Ответ принят как подходящий

Альтернативой является использование неэкви-соединения и использование рычага .EACHI:

treesData[aggtable,on=.(Height>=bin1, Height<bin2),.(ct = .N, Girth = sum(Girth)),.EACHI]

Выход:

   Height Height    ct Girth
    <num>  <num> <int> <num>
1:     63     66     3  31.2
2:     66     69     1  11.0
3:     69     72     3  33.7
4:     72     75     4  53.9
5:     75     78     6  73.3
6:     78     81     7 104.5
7:     81     84     4  56.3
8:     84     87     2  26.2
9:     87     90     1  20.6

Обратите внимание, что неэквивалентные соединения в data.table могут привести к путанице в отношении именования. Более полный вариант может быть:

aggtable = treesData[aggtable,on=.(Height>=bin1, Height<bin2),.(ct = .N, Girth = sum(Girth)),.EACHI]
setnames(aggtable, new=c("Bin1", "Bin2", "Count", "Girth.sum"))

Спасибо. Это то, что вы бы посоветовали, если бы я захотел сделать дальше aggtable[,Count := treesData[aggtable,on=.(Height>=bin1, Height<bin2),.(Count= .N, Girth.sum = sum(Girth)),.EACHI]$Count]; aggtable[,Girth.sum:= treesData[aggtable,on=.(Height>=bin1, Height<bin2),.(Count= .N, Girth.sum = sum(Girth)),.EACHI]$Girth.sum]; Это я делаю, чтобы 1) создать соответствующий столбец в aggtable и 2) чтобы не отображать вывод в консоли.

Mohit 15.07.2024 06:42

Этот тип подхода является более общим и приводит к процедуре, которая имеет более высокую статистическую эффективность: использование движущихся окон (перекрывающихся ячеек).

Frank Harrell 15.07.2024 13:28

@Мохит, на самом деле я бы не рекомендовал этого, потому что вы выполняете соединение дважды, по одному для каждой переменной. Смотрите мое обновление

langtang 15.07.2024 18:41

Другие вопросы по теме