1) dplyr
Вот подход dplyr
, но начинающийся с reshape
(который имеет большую функциональность, но способ работы его аргументов невозможно запомнить).
library(dplyr)
(df2 <- reshape(df1, varying = c("Y.1", "Y.2", "Y.3"), direction = "long") %>%
group_by(Y))
# A tibble: 9 x 7
# Groups: Y [6]
# X M.1 M.2 M.3 time Y id
#* <chr> <int> <int> <int> <dbl> <chr> <int>
#1 K3 21 6 11 1 L 1
#2 K8 31 1 29 1 N 2
#3 K2 8 0 2 1 L 3
#4 K3 21 6 11 2 N 1
#5 K8 31 1 29 2 NA 2
#6 K2 8 0 2 2 Q 3
#7 K3 21 6 11 3 X 1
#8 K8 31 1 29 3 NA 2
#9 K2 8 0 2 3 Z 3
Теперь мы можем использовать left_join
после того, как суммировали X
и c("M.1", "M.2", "M.3")
отдельно.
left_join(
summarise_at(df2, c("M.1", "M.2", "M.3"), .funs = sum),
mmarise(df2, X = toString(unique(X)))
)
# A tibble: 6 x 5
# Y M.1 M.2 M.3 X
# <chr> <int> <int> <int> <chr>
#1 L 29 6 13 K3, K2
#2 N 52 7 40 K8, K3
#3 Q 8 0 2 K2
#4 X 21 6 11 K3
#5 Z 8 0 2 K2
#6 NA 62 2 58 K8
2) основание R
Начиная с df2
, та же идея есть в base R
, но обратите внимание, что NA
s потеряно.
df2 <- reshape(df1, varying = c("Y.1", "Y.2", "Y.3"), direction = "long")
merge(
aggregate(cbind(M.1, M.2, M.3) ~ Y, df2, sum),
aggregate(X ~ Y, df2, toString)
)
# Y M.1 M.2 M.3 X
#1 L 29 6 13 K3, K2
#2 N 52 7 40 K8, K3
#3 Q 8 0 2 K2
#4 X 21 6 11 K3
#5 Z 8 0 2 K2
3) data.table
library(data.table)
setDT(df1)
df2 <- melt(df1, measure.vars = patterns("Y."), value.name = "Y")
# I'm sure there must be a cleverer way than this
df2[df2[, .(X = toString(unique(X))), by = Y], lapply(.SD, sum), .SDcols = c("M.1", "M.2", "M.3"), by = Y, on = "Y"]
данные
df1 <- structure(list(X = c("K3", "K8", "K2"), M.1 = c(21L, 31L, 8L),
M.2 = c(6L, 1L, 0L), M.3 = c(11L, 29L, 2L), Y.1 = c("L",
"N", "L"), Y.2 = c("N", NA, "Q"), Y.3 = c("X", NA, "Z")), .Names = c("X",
"M.1", "M.2", "M.3", "Y.1", "Y.2", "Y.3"), class = "data.frame", row.names = c(NA,
-3L))