gpt4 book ai didi

r - 爆炸日期范围为 R

转载 作者:行者123 更新时间:2023-12-04 18:13:02 25 4
gpt4 key购买 nike

我有一个表格的数据集:

df <- data.frame(var1 = c("1976-07-04" , "1980-07-04" , "1984-07-04" ), 
var2 = c('d', 'e', 'f'),
freq = 1:3)

我可以通过以下方式使用索引非常快速地扩展此 data.frame:
df.expanded <- df[rep(seq_len(nrow(df)), df$freq), ]

但是,我想在日期创建一个序列而不是复制,并让频率告诉我这个的长度。即对于第 3 行,我可以创建条目以填充爆炸的 data.frame:
seq(as.Date('1984-7-4'), by = 'days', length = 3)

谁能建议一种快速的方法来做到这一点?我的方法是使用各种 lapply 函数来做到这一点

我结合了 Gavin Simpson 的答案和以前的想法来解决我的问题。
ExtendedSeq <- function(df, freq.col, date.col, period = 'month') {
#' An R function to take a data fame that has a frequency col and explode the
#' the dataframe to have that number of rows and based on a sequence.
#' Args:
#' df: A data.frame to be exploded.
#' freq.col: A column variable indicating the number of replicates in the
#' new dataset to make.
#' date.col: A column variable indicating the name or position of the date
#' variable.
#' period: The periodicity to apply to the date.

# Replicate expanded data form
df.expanded <- df[rep(seq_len(nrow(df)), df[[freq.col]]), ]

DateExpand <- function(row, df.ex, freq, col.date, period) {
#' An inner functions to explode a data set and build out days sequence
#' Args:
#' row: Each row of a data set
#' df.ex: A data.frame, to expand
#' freq: Column indicating the number of replicates to make.
#' date: Column indicating the date variable
#' Output:
#' An exploded data set based on a sequence expansion of a date.
times <- df.ex[row, freq]
# period <- can edit in the future if row / data driven.
date.ex <- seq(df.ex[row, col.date], by = "days", length = times)
return(date.ex)
}

dates <- lapply(seq_len(nrow(df)),
FUN = DateExpand,
df.ex = df,
freq = freq.col,
col.date = date.col,
period = period)

df.expanded[[date.col]] <- as.Date(unlist(dates), origin = '1970-01-01')
row.names(df.expanded) <- NULL
return(df.expanded)
}

就我个人而言,我不喜欢我需要从列表中隐藏日期并根据此转换提供来源的方式,以防将来发生变化,但我非常感谢这些想法和帮助

最佳答案

这是一种方法:

extendDF <- function(x) {
foo <- function(i, z) {
times <- z[i, "freq"]
out <- data.frame(seq(z[i, 1], by = "days", length = times),
rep(z[i, 2], times),
rep(z[i, 3], times))
names(out) <- names(z)
out
}
out <- lapply(seq_len(nrow(x)), FUN = foo, z = x)
do.call("rbind", out)
}

这会迭代索引 1:nrow(df) (即 df 的行索引)应用内联函数 foodf 的每一行. foo()基本上只是扩展 var2freq一个 freq次数并使用您的 seq()要求延长 var1 .该函数对列顺序、名称等进行了一些假设,但您可以根据需要进行修改。

唯一的另一点是转换 var1 的效率要高得多。到 "Date" extendDF() 中的所有对象而不是每一行依次,因此首先进行一次转换,这里使用 transform() :
df <- transform(df, var1 = as.Date(var1))

然后调用 extendDF()
extendDF(df)

这给出了:
R> df <- transform(df, var1 = as.Date(var1))
R> extendDF(df)
var1 var2 freq
1 1976-07-04 d 1
2 1980-07-04 e 2
3 1980-07-05 e 2
4 1984-07-04 f 3
5 1984-07-05 f 3
6 1984-07-06 f 3

关于r - 爆炸日期范围为 R,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12246026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com