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
连接 x5
和 x6
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()
.
我想知道如果应用于更大的数据集,这段代码与 相比速度如何。
我有这样一个数据框:
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
连接 x5
和 x6
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()
.
我想知道如果应用于更大的数据集,这段代码与