如果我的数据不是时间序列而是大量的文本行,使用什么代替 'lag'

What to use instead of 'lag' if my data is not time series but just large set of text rows

我的数据文件是许多结构相似的文本文件的合并:

  1. 行"START OF NEW FILE ",
  2. 行与文件名,
  3. '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")