1) janitor Используйте adorn_totals
из пакета janitor, игнорируя столбец Total. Обратите внимание, что в разделе group_by
эта точка относится ко всему набору данных, а не только к этой группе, если только мы не ссылаемся на нее в пределах do
, поэтому мы используем do
.
library(janitor)
res1 <- arrests %>%
select(-Total) %>%
group_by(State) %>%
do(adorn_totals(select(., -State), "row")) %>%
ungroup
res1
давая:
# A tibble: 250 x 3
State Crime Value
<chr> <chr> <dbl>
1 Alabama Murder 13.2
2 Alabama Assault 236
3 Alabama UrbanPop 58
4 Alabama Rape 21.2
5 Alabama Total 328.
6 Alaska Murder 10
7 Alaska Assault 263
8 Alaska UrbanPop 48
9 Alaska Rape 44.5
10 Alaska Total 366.
# ... with 240 more rows
Мы можем удалить строки Total и добавить столбец
res1 %>% {
left <- filter(., Crime != "Total")
right <- filter(., Crime == "Total") %>% select(State, Total = Value)
left_join(left, right, by = "State")
}
2) reshape2 Пакет reshape2 является предшественником функций pivot_ * , Он имеет встроенную функциональность полей, которая, по-видимому, не была продолжена в последующих итерациях в распространение / сборка и pivot_ *. Это также работает, если мы заменим оператор library
на library(data.table)
.
library(reshape2)
res2 <- dcast(arrests, State + Crime ~ "Value", fun.aggregate = sum,
value.var = "Value", margins = "Crime")
res2
, давая:
State Crime Value
1 Alabama Assault 236.0
2 Alabama Murder 13.2
3 Alabama Rape 21.2
4 Alabama UrbanPop 58.0
5 Alabama (all) 328.4
6 Alaska Assault 263.0
7 Alaska Murder 10.0
8 Alaska Rape 44.5
9 Alaska UrbanPop 48.0
10 Alaska (all) 365.5
...etc...
Чтобы создать столбец Total и удалить строки, создайте фактор который идентифицирует каждую строку как строку значения или итога, а затем выводит результат в широкие формы, заполняя в NA с na.locf
.
library(reshape2)
library(zoo)
fac <- factor(res$Crime == '(all)', labels = c("Value", "Total"))
dc <- dcast(res2, State + Crime ~ fac, value.var = "Value")
subset(na.locf(dc, fromLast = TRUE), Crime != '(all)')
или
left <- subset(res2, Crime != "(all)")
right <- subset(res2, Crime == "(all)", c(State, Value))
names(right) <- c("State", "Total")
merge(left, right, by = "State")
3) sqldf Чтобы использовать SQL, добавьте столбец уровня, который равен 0 для подробных записей и 1 для итоговых записей, а затем объедините детали и итоги и выполните сортировку.
library(sqldf)
res3 <- sqldf("select State, Crime, Value from (
select 0 as level, State, Crime, Value from arrests
union
select 1 as level, State, 'Total' as Crime, sum(Value) as Total from arrests
group by State)
order by State, level")
Чтобы удалить итоговые строки и вставить a Итоговый столбец
sqldf("select State, Crime, Value, Total
from res3 a
left join (
select State, sum(Value) as Total
from res3
where Crime != 'Total'
group by State) using (State)
where Crime != 'Total'")
4) База R Это прямо в базе R с использованием xtabs
и addmargins
.
Total <- sum
tab <- addmargins(xtabs(Value ~ State + Crime, arrests), 2, FUN = Total)
DF <- as.data.frame(tab, responseName = "Value")
res3 <- DF[order(DF$State, DF$Crime == "Total"), ]
и модификацией ( 2) мы можем использовать следующее для удаления строк Total и добавления столбца Total:
left <- subset(res3, Crime != "Total")
right <- subset(res3, Crime == "Total", c(State, Value))
names(right) <- c("State", "Total")
merge(left, right, by = "State")