我有一个非常大的数据框,其中包括整数列state
和state_cyclen
.每一行都是一个GameFrame,而state
描述游戏在该帧所处的状态,state_cyclen
被编码以指示该状态的n次出现(基本上是data.table::rleid(state)
).条件为state
,循环为state_cyclen
我需要从其他定义数据框中导入几列.定义数据框存储有关状态的属性,它们的行顺序通知这些属性在整个游戏中循环的方式(玩家多次遇到每个游戏状态).
以下是应该保持连接的长数据的最小示例:
data <- data.frame(
state = c(1, 1, 2, 2, 3, 3, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3, 3, 4, 4, 3, 3),
state_cyclen = c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 4, 4)
)
data
#> state state_cyclen
#> 1 1 1
#> 2 1 1
#> 3 2 1
#> 4 2 1
#> 5 3 1
#> 6 3 1
#> 7 1 2
#> 8 1 2
#> 9 2 2
#> 10 2 2
#> 11 3 2
#> 12 3 2
#> 13 2 3
#> 14 2 3
#> 15 3 3
#> 16 3 3
#> 17 3 3
#> 18 4 1
#> 19 4 1
#> 20 3 4
#> 21 3 4
存储排序的定义数据帧的最小示例:
def_one <- data.frame(
prop = letters[1:3],
others = LETTERS[1:3]
)
def_two <- data.frame(
prop = letters[4:10],
others = LETTERS[4:10]
)
def_three <- data.frame(
prop = letters[11:12],
others = LETTERS[11:12]
)
我有一个用基数R编写的解决方案,它可以提供所需的输出,但它的可读性不是很好,也可能不是很高效.
# Add empty columns
data$prop <- NA
data$others <- NA
# Function that recycles numeric vector bounded by a upper limit
bounded_vec_recyc <- function(vec, n) if(n == 1) vec else (vec - 1) %% n + 1
# My solution
vec_pos_one <- data[data[, "state"] == 1, ]$state_cyclen
vec_pos_one <- bounded_vec_recyc(vec_pos_one, n = nrow(def_one))
data[data[, "state"] == 1, ][, c("prop", "others")] <- def_one[vec_pos_one,]
vec_pos_two <- data[data[, "state"] == 2, ]$state_cyclen
vec_pos_two <- bounded_vec_recyc(vec_pos_two, n = nrow(def_two))
data[data[, "state"] == 2, ][, c("prop", "others")] <- def_two[vec_pos_two,]
vec_pos_three <- data[data[, "state"] == 3, ]$state_cyclen
vec_pos_three <- bounded_vec_recyc(vec_pos_three, n = nrow(def_three))
data[data[, "state"] == 3, ][, c("prop", "others")] <- def_three[vec_pos_three,]
data
#> state state_cyclen prop others
#> 1 1 1 a A
#> 2 1 1 a A
#> 3 2 1 d D
#> 4 2 1 d D
#> 5 3 1 k K
#> 6 3 1 k K
#> 7 1 2 b B
#> 8 1 2 b B
#> 9 2 2 e E
#> 10 2 2 e E
#> 11 3 2 l L
#> 12 3 2 l L
#> 13 2 3 f F
#> 14 2 3 f F
#> 15 3 3 k K
#> 16 3 3 k K
#> 17 3 3 k K
#> 18 4 1 <NA> <NA>
#> 19 4 1 <NA> <NA>
#> 20 3 4 l L
#> 21 3 4 l L
创建于2022-08-30,共reprex v2.0.2个
TLDR:如你所见,我基本上是试图将这些定义数据框一个接一个地合并到对应state
上的主数据框中,方法是循环使用定义数据框的行,同时保持它们的顺序,使用state_cyclen
列在整个游戏中跟踪每个状态的发生情况.
有没有一种方法可以在tidyverse
或data.table
范围内做到这一点,更快,或者至少更容易阅读?我需要这是相当快的,因为我有许多这样的GameFrame文件(在数百),他们是长的(数十万行).
附注:我不确定标题是否适合我正在进行的操作,因为我可以想象多种实现方式.欢迎对其进行编辑.