【问题标题】:Data mutate in RR中的数据变异
【发布时间】:2018-04-13 17:59:03
【问题描述】:

我有一个这样的数据框:

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

我想根据对应的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 值组合在一起,请选择最小值。例如,x1 as Var2 连接 x5x6 作为 Var1 并且值为 min(x5,x6)=2

有什么想法吗?

【问题讨论】:

  • 这两个数据集有什么关系?这个问题需要澄清,因为不可能知道您要达到的目标。
  • 我想这就是你需要的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]))) }))
  • 或使用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)}, Var2]

标签: r dplyr reshape2


【解决方案1】:

根据描述,我们需要做一个groupby combn来得到'pairs'的min'value'。 base R 选项是通过“Var2”到split,然后在“Var1”上执行combn,通过对每个“Var1”的相应值进行子集化来获得“值”的min

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))

【讨论】:

  • 感谢@akrun,很好的解决方案。我在更大的数据集上测试了它们,并且运行良好。再次感谢。
【解决方案2】:

还有一个使用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 &lt; rn 替换combn()

如果应用于更大的数据集,我想知道这段代码在速度方面与 akrun's solutions 相比如何。

【讨论】:

    猜你喜欢
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-17
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    • 1970-01-01
    相关资源
    最近更新 更多