如何在 R 中使用滚动变量构建序列
How to build a sequence using a rolling variable in R
我正在尝试构建一个采用先前值并将其添加到序列中的序列。
例如:
Var1 Var2
1 A
1 B
1 C
2 A
2 C
2 D
我正在寻找的输出是:
Var1 Var2 Var3
1 A A
1 B A>B
1 C A>B>C
2 A A
2 C A>C
2 D A>C>D
有这个包吗?序列中的元素数量可能会变得非常大,因此如果不将同一段代码写出 n 次(其中 n 是序列中元素的最大数量),我目前在 dplyr 中使用滞后的方法是不可行的。
您可以使用 by()
并利用有用的 R factor
。我们通过 transform/re-transform 得到 "numeric"
s 到因子并返回。使用 Map
生成增长的 seq
uences,再次转换为因子并根据 Var2
分配标签,使用 ">"
折叠。 c
oncatenate 和 unlist
一切,你会得到 "Var3"
。 (不过在大数据帧中可能会很慢。)
dat$Var3 <- unlist(do.call(c, by(dat, dat$Var1, function(s) {
r <- Map(seq, as.numeric(factor(s$Var2)))
r <- lapply(r, levels=1:3, labels=s$Var2, factor)
return(Map(paste, r, collapse=">"))
})))
dat
# Var1 Var2 Var3
# 1 1 A A
# 2 1 B A>B
# 3 1 C A>B>C
# 4 2 A A
# 5 2 C A>C
# 6 2 D A>C>D
数据
dat <- structure(list(Var1 = c(1L, 1L, 1L, 2L, 2L, 2L), Var2 = c("A",
"B", "C", "A", "C", "D")), row.names = c(NA, -6L), class = "data.frame")
你可以这样做:
transform(dat, Var3 = ave(Var2, Var1, FUN = function(x) sapply(seq_along(x), function(i) paste(x[1:i], collapse = ">"))))
Var1 Var2 Var3
1 1 A A
2 1 B A>B
3 1 C A>B>C
4 2 A A
5 2 C A>C
6 2 D A>C>D
我建议你包 runner for sequential functions. Function runner::runner 应用传递给 f
的任何 R 函数(需要指定输出 type
)
# data
df <- data.frame(
var1 = rep(c(1,2), each = 3),
var2 = rep(c("A", "B", "C"), 2))
# result
library(dplyr)
library(runner)
df %>%
group_by(var1) %>%
mutate(var3 = runner(var2,
function(x) paste(x, collapse = ">"),
type = "character"))
# var1 var2 var3
# <dbl> <fct> <chr>
# 1 1 A A
# 2 1 B A>B
# 3 1 C A>B>C
# 4 2 A A
# 5 2 B A>B
# 6 2 C A>B>C
检查 documentation 以获得更多选项
我正在尝试构建一个采用先前值并将其添加到序列中的序列。
例如:
Var1 Var2
1 A
1 B
1 C
2 A
2 C
2 D
我正在寻找的输出是:
Var1 Var2 Var3
1 A A
1 B A>B
1 C A>B>C
2 A A
2 C A>C
2 D A>C>D
有这个包吗?序列中的元素数量可能会变得非常大,因此如果不将同一段代码写出 n 次(其中 n 是序列中元素的最大数量),我目前在 dplyr 中使用滞后的方法是不可行的。
您可以使用 by()
并利用有用的 R factor
。我们通过 transform/re-transform 得到 "numeric"
s 到因子并返回。使用 Map
生成增长的 seq
uences,再次转换为因子并根据 Var2
分配标签,使用 ">"
折叠。 c
oncatenate 和 unlist
一切,你会得到 "Var3"
。 (不过在大数据帧中可能会很慢。)
dat$Var3 <- unlist(do.call(c, by(dat, dat$Var1, function(s) {
r <- Map(seq, as.numeric(factor(s$Var2)))
r <- lapply(r, levels=1:3, labels=s$Var2, factor)
return(Map(paste, r, collapse=">"))
})))
dat
# Var1 Var2 Var3
# 1 1 A A
# 2 1 B A>B
# 3 1 C A>B>C
# 4 2 A A
# 5 2 C A>C
# 6 2 D A>C>D
数据
dat <- structure(list(Var1 = c(1L, 1L, 1L, 2L, 2L, 2L), Var2 = c("A",
"B", "C", "A", "C", "D")), row.names = c(NA, -6L), class = "data.frame")
你可以这样做:
transform(dat, Var3 = ave(Var2, Var1, FUN = function(x) sapply(seq_along(x), function(i) paste(x[1:i], collapse = ">"))))
Var1 Var2 Var3
1 1 A A
2 1 B A>B
3 1 C A>B>C
4 2 A A
5 2 C A>C
6 2 D A>C>D
我建议你包 runner for sequential functions. Function runner::runner 应用传递给 f
的任何 R 函数(需要指定输出 type
)
# data
df <- data.frame(
var1 = rep(c(1,2), each = 3),
var2 = rep(c("A", "B", "C"), 2))
# result
library(dplyr)
library(runner)
df %>%
group_by(var1) %>%
mutate(var3 = runner(var2,
function(x) paste(x, collapse = ">"),
type = "character"))
# var1 var2 var3
# <dbl> <fct> <chr>
# 1 1 A A
# 2 1 B A>B
# 3 1 C A>B>C
# 4 2 A A
# 5 2 B A>B
# 6 2 C A>B>C
检查 documentation 以获得更多选项