【问题标题】:Building a data frame with sentences of different lengths用不同长度的句子构建数据框
【发布时间】:2015-12-18 18:59:46
【问题描述】:

我想构建一个包含例如 9 列的数据框,并且我使用日志文件作为我的输入。对于前 8 列,我知道该文件被空格整齐地分隔。但第 9 列是由单词和变量组成的消息,也由空格分隔。

V1  V2       V3        V4        V5     V6     V7 V8                V9

1a lo_Out [12/4/15 12:36:01:367 GMT] 000000be con J   This is a message N characters long
1a lo_In  [12/4/15 12:36:01:403 GMT] 0000008c Com W   This is a message N characters long
2a lo_Out [12/4/15 12:36:01:404 GMT] 0000008c con J   This is a message N characters long
2a lo_In  [12/4/15 12:36:01:404 GMT] 000000be Com X   This is a message N characters long

那么,我可以读入文件并停止我的代码尝试在最后一列上分离,然后将剩余部分转储到最后一列吗?

这就是我使用类似的 Apache 通用日志格式所做的……但是所有向量的长度都相同。正是那条被空格隔开的信息让我很生气。数据框甚至是解决此问题的正确方法吗?

### First read in the logfile
logfile <- 'logfile.net-Nov-2015';


data_dt <- fread(logfile, sep = ' ');

### Load and rename important columns
data_dt[, ip_address  := as.character(V1)];
data_dt[, timestamp   := paste(V4, V5)];
data_dt[, request     := V6];
data_dt[, http_status := V7];
data_dt[, return_size := V8];
data_dt[, referer     := V9];
data_dt[, user_agent  := V10];

【问题讨论】:

  • 如果您编辑输入数据,我们很难给您准确的答案
  • 抱歉,当我看到您的回答时我意识到,我的数据不准确。我的坏
  • 我用你的新场景更新了答案
  • 这真的是一个类似 CSV 的文件,还是一个固定宽度的文件,其中每一列都从具有固定长度的预定义位置开始(最后一列除外)?要读取固定宽度的文件,您可以使用 read.fwf
  • 是的 R Yoda,您的描述将是描述文件的更好方式。我看看 read.fwf

标签: r data.table


【解决方案1】:

尝试在read.table 中使用quote 选项:

data_dt <- read.table(logfile, sep = " ", quote = "\"", header = FALSE)

更多详情,请阅读文档:read.table

编辑:

如果你没有带引号的字符串,你可以尝试如下重构第九列。

首先,让我们使用一些可重现的数据进行测试,这些数据可以存储在一个名为“log.txt”的文件中。单个字母代表您的话。

logfile_content <- "aaa bbb ccc ddd eee fff ggg hhh i j k
aaa bbb ccc ddd eee fff ggg hhh l m
aaa bbb ccc ddd eee fff ggg hhh 
aaa bbb ccc ddd eee fff ggg hhh n o p q r s t
aaa bbb ccc ddd eee fff ggg hhh u
"
write(logfile_content, "log.txt")

使用额外参数读取文件。 fill 将为那些列数小于最大值的行生成缺失值。 na.strings 会将这些缺失值转换为 NAstringsAsFactors 用于处理纯字符串。

data_dt <- read.table("log.txt", sep = " ", header = FALSE, 
                      fill = TRUE, stringsAsFactors = FALSE, na.strings = "")

要重构最后一列,您可以对每一行使用apply paste 函数。

V9 <- apply(data_dt[,9:ncol(data_dt)], MARGIN=1, FUN=function(v) paste(na.omit(v), collapse=" "))

然后你可以将你的前 8 列与重构的第九列结合起来

(data_dt2 <- cbind(data_dt[,1:8], V9))
   V1  V2  V3  V4  V5  V6  V7  V8            V9
1 aaa bbb ccc ddd eee fff ggg hhh         i j k
2 aaa bbb ccc ddd eee fff ggg hhh           l m
3 aaa bbb ccc ddd eee fff ggg hhh              
4 aaa bbb ccc ddd eee fff ggg hhh n o p q r s t
5 aaa bbb ccc ddd eee fff ggg hhh             u

请注意,如果您的日志文件很大,这可能效果不佳。我很确定使用data.table 可以更好地实现这样的事情,但我不知道如何。希望这对您来说是一个好的开始。

【讨论】:

  • 这是一个巨大的日志文件,但这是一个很好的开始,稍后我会担心性能问题。谢谢
  • 这样的话,我建议你使用Apache Spark
猜你喜欢
  • 2021-05-27
  • 2023-03-16
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-16
  • 2013-11-13
  • 1970-01-01
相关资源
最近更新 更多