我的数据文件是许多结构相似的文本文件的合并:
- 行“新文件开始”,
- 行与文件名,
- “数据线”有两列:域和事件数
每个文件的此类“数据行”数量可能从 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
是不是因为我的数据不是实时序列?或者因为应该添加一些技巧来解决第一行缺少“上一个”行的问题?还是别的?
附言期望的输出是这样的(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
对行进行分组,对于从第一个 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 此基本解决方案类似于 (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")
关于r - 如果我的数据不是时间序列而是大量文本行,应该使用什么代替 'lag',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51862635/