R 中的数据变异

Data mutate in R

我有这样一个数据框:

Var1 Var2 value
x5   x1   2
x6   x1   6
x1   x2   2
x5   x2   2
x6   x2   4
x7   x2   3

并且我想reshape/aggregate/summarise它根据相应的Var2和每对Var1的最小值,就像这样:

Var3 Var4 minvalue
x5   x6   2
x1   x5   2
x1   x6   2
x1   x7   2
x5   x6   2
x5   x7   2
x6   x7   3

如果您将 Var1 值与对应的 Var2 值组合 select 最小值。例如 x1 as Var2 连接 x5x6 as Var1 并且值为 min(x5,x6)=2

有什么想法吗?

根据描述,我们需要做一个 groupby combn 来得到 'pairs' 的 min 'value'。 base R 选项是 'Var2' 到 split,然后在 'Var1' 上执行 combn,得到 [=28= 的 min ] 通过对每个 'Var1'

的相应值进行子集化
res <- do.call(rbind, lapply(split(df1[-2], df1$Var2), function(x) {
       x1 <- combn(x$Var1, 2, FUN = list)
      data.frame(do.call(rbind, x1),minvalue = sapply(x1, function(y) 
                 min(x$value[x$Var1 %in% y]))) }))
row.names(res) <- NULL
res
#  X1 X2 minvalue
#1 x5 x6        2
#2 x1 x5        2
#3 x1 x6        2
#4 x1 x7        2
#5 x5 x6        2
#6 x5 x7        2
#7 x6 x7        3

或者我们可以使用 data.table,按 'Var2' 分组,像之前那样执行 combn

library(data.table)
setDT(df1)[, {
         x1 <- combn(Var1, 2, FUN = list)
         data.frame(do.call(rbind, x1), 
              minvalue = sapply(x1, function(y) min(value[Var1 %in% y])),
             stringsAsFactors= FALSE)
           }, by = Var2]

数据

df1 <- structure(list(Var1 = c("x5", "x6", "x1", "x5", "x6", "x7"), 
Var2 = c("x1", "x1", "x2", "x2", "x2", "x2"), value = c(2L, 
6L, 2L, 2L, 4L, 3L)), .Names = c("Var1", "Var2", "value"),
class = "data.frame", row.names = c(NA, -6L))

有一个替代解决方案使用 data.table's non-equi join

library(data.table)
setDT(df1)[, rn := .I][
  df1, on = .(Var2, rn < rn), nomatch = 0L, allow = TRUE,
  .(Var3 = Var1, Var4 = i.Var1, minvalue = pmin(value, i.value))]
   Var3 Var4 minvalue
1:   x5   x6        2
2:   x1   x5        2
3:   x1   x6        2
4:   x5   x6        2
5:   x1   x7        2
6:   x5   x7        2
7:   x6   x7        3

Var2 上的连接相当于按 Var2 分组,而行号上的连接条件 rn < rn 替换 combn().

我想知道如果应用于更大的数据集,这段代码与 相比速度如何。