如果我的数据不是时间序列而是大量的文本行,使用什么代替 'lag'
What to use instead of 'lag' if my data is not time series but just large set of text rows
我的数据文件是许多结构相似的文本文件的合并:
- 行"START OF NEW FILE ",
- 行与文件名,
- 'data lines' 有两列:域和事件数
每个文件的 'data lines' 数量可能从 0 到数十万不等
目标是添加新列,每一行将指示它相关的文件名
这是数据样本:
DF <- structure(list(domain = c("START OF NEW FILE", "94_res.txt",
"google.ru", "START OF NEW FILE", "95_res.txt", "search-results.com",
"hpc.ru", "theadgateway.com", "google.by"), count = c(NA, NA,
2L, NA, NA, 2L, 1L, 1L, 6L)), row.names = c(NA, -9L), class = "data.frame")
我使用 lag
或类似功能的所有尝试都失败了。下面的示例是我的最佳尝试,但根据当前行值而不是上一行值填充新列。
transform(test.df,
fnameRaw = ifelse(lag(test.df$domain, 1) == "START OF NEW FILE ",
test.df$domain,
""))
domain count fnameRaw
1 START OF NEW FILE START OF NEW FILE
2 94_res.txt
3 google.ru 2
4 START OF NEW FILE START OF NEW FILE
5 95_res.txt
6 search-results.com 2
7 hpc.ru 1
8 theadgateway.com 1
9 google.by 6
是不是因为我的数据不是实时序列?或者因为应该添加一些技巧来解决第一行缺少 'previous' 行的问题?还是别的?
P.S。期望的输出是这样的(fnameRaw 只是为了与实际输出进行比较而保留的中间字段)
domain count fnameRaw filename
1 START OF NEW FILE N/A
2 94_res.txt 94_res.txt 94_res.txt
3 google.ru 2 94_res.txt
4 START OF NEW FILE 94_res.txt
5 95_res.txt 95_res.txt 95_res.txt
6 search-results.com 2 95_res.txt
7 hpc.ru 1 95_res.txt
8 theadgateway.com 1 95_res.txt
9 google.by 6 95_res.txt
lag
用于时间序列,但如果您使用 dplyr,则有一个 lag
适用于数据帧。
1) dplyr/lag 我们可以这样使用 lag
:
library(dplyr)
library(zoo)
DF %>%
mutate(filename = ifelse(lag(domain) == "START OF NEW FILE", domain, NA),
filename = na.locf0(filename),
filename = ifelse(domain == "START OF NEW FILE", NA, filename))
给予:
domain count filename
1 START OF NEW FILE NA <NA>
2 94_res.txt NA 94_res.txt
3 google.ru 2 94_res.txt
4 START OF NEW FILE NA <NA>
5 95_res.txt NA 95_res.txt
6 search-results.com 2 95_res.txt
7 hpc.ru 1 95_res.txt
8 theadgateway.com 1 95_res.txt
9 google.by 6 95_res.txt
2) dplyr/no lag 没有 lag
我们可以使用分组变量 g
对行进行分组,该变量从 1 开始第一个 START OF NEW FILE
,第二个行为 2,依此类推。
library(dplyr)
DF %>%
group_by(g = cumsum(domain == "START OF NEW FILE")) %>%
mutate(filename = c(NA, rep(domain[2], n()-1))) %>%
ungroup %>%
select(-g)
2a) Base R/no lag 这个base解和(2)类似。创建一个向量 g
,每行一个元素 DF
,其元素为 1,从第一行 START OF NEW FILE
开始,2 从第二行开始,依此类推。然后定义一个函数 make_filename
,它为 g
定义的一组创建 filename
列。最后将 make_function
应用于每个组。没有使用包。
g <- cumsum(DF$domain == "START OF NEW FILE")
make_Filename <- function(x) c(NA, rep(x[2], length(x) - 1))
transform(DF, filename = ave(DF$domain, g, FUN = make_filename))
备注
可重现形式的输入DF
是:
DF <- structure(list(domain = c("START OF NEW FILE", "94_res.txt",
"google.ru", "START OF NEW FILE", "95_res.txt", "search-results.com",
"hpc.ru", "theadgateway.com", "google.by"), count = c(NA, NA,
2L, NA, NA, 2L, 1L, 1L, 6L)), row.names = c(NA, -9L), class = "data.frame")
我的数据文件是许多结构相似的文本文件的合并:
- 行"START OF NEW FILE ",
- 行与文件名,
- 'data lines' 有两列:域和事件数
每个文件的 'data lines' 数量可能从 0 到数十万不等 目标是添加新列,每一行将指示它相关的文件名
这是数据样本:
DF <- structure(list(domain = c("START OF NEW FILE", "94_res.txt",
"google.ru", "START OF NEW FILE", "95_res.txt", "search-results.com",
"hpc.ru", "theadgateway.com", "google.by"), count = c(NA, NA,
2L, NA, NA, 2L, 1L, 1L, 6L)), row.names = c(NA, -9L), class = "data.frame")
我使用 lag
或类似功能的所有尝试都失败了。下面的示例是我的最佳尝试,但根据当前行值而不是上一行值填充新列。
transform(test.df,
fnameRaw = ifelse(lag(test.df$domain, 1) == "START OF NEW FILE ",
test.df$domain,
""))
domain count fnameRaw
1 START OF NEW FILE START OF NEW FILE
2 94_res.txt
3 google.ru 2
4 START OF NEW FILE START OF NEW FILE
5 95_res.txt
6 search-results.com 2
7 hpc.ru 1
8 theadgateway.com 1
9 google.by 6
是不是因为我的数据不是实时序列?或者因为应该添加一些技巧来解决第一行缺少 'previous' 行的问题?还是别的?
P.S。期望的输出是这样的(fnameRaw 只是为了与实际输出进行比较而保留的中间字段)
domain count fnameRaw filename
1 START OF NEW FILE N/A
2 94_res.txt 94_res.txt 94_res.txt
3 google.ru 2 94_res.txt
4 START OF NEW FILE 94_res.txt
5 95_res.txt 95_res.txt 95_res.txt
6 search-results.com 2 95_res.txt
7 hpc.ru 1 95_res.txt
8 theadgateway.com 1 95_res.txt
9 google.by 6 95_res.txt
lag
用于时间序列,但如果您使用 dplyr,则有一个 lag
适用于数据帧。
1) dplyr/lag 我们可以这样使用 lag
:
library(dplyr)
library(zoo)
DF %>%
mutate(filename = ifelse(lag(domain) == "START OF NEW FILE", domain, NA),
filename = na.locf0(filename),
filename = ifelse(domain == "START OF NEW FILE", NA, filename))
给予:
domain count filename
1 START OF NEW FILE NA <NA>
2 94_res.txt NA 94_res.txt
3 google.ru 2 94_res.txt
4 START OF NEW FILE NA <NA>
5 95_res.txt NA 95_res.txt
6 search-results.com 2 95_res.txt
7 hpc.ru 1 95_res.txt
8 theadgateway.com 1 95_res.txt
9 google.by 6 95_res.txt
2) dplyr/no lag 没有 lag
我们可以使用分组变量 g
对行进行分组,该变量从 1 开始第一个 START OF NEW FILE
,第二个行为 2,依此类推。
library(dplyr)
DF %>%
group_by(g = cumsum(domain == "START OF NEW FILE")) %>%
mutate(filename = c(NA, rep(domain[2], n()-1))) %>%
ungroup %>%
select(-g)
2a) Base R/no lag 这个base解和(2)类似。创建一个向量 g
,每行一个元素 DF
,其元素为 1,从第一行 START OF NEW FILE
开始,2 从第二行开始,依此类推。然后定义一个函数 make_filename
,它为 g
定义的一组创建 filename
列。最后将 make_function
应用于每个组。没有使用包。
g <- cumsum(DF$domain == "START OF NEW FILE")
make_Filename <- function(x) c(NA, rep(x[2], length(x) - 1))
transform(DF, filename = ave(DF$domain, g, FUN = make_filename))
备注
可重现形式的输入DF
是:
DF <- structure(list(domain = c("START OF NEW FILE", "94_res.txt",
"google.ru", "START OF NEW FILE", "95_res.txt", "search-results.com",
"hpc.ru", "theadgateway.com", "google.by"), count = c(NA, NA,
2L, NA, NA, 2L, 1L, 1L, 6L)), row.names = c(NA, -9L), class = "data.frame")