如何解析数据帧列表中的数百个 csvs 的内容并拆分为“;”和 ”;”在循环中?

How do I parse the contents of hundreds of csvs that are in a list of dataframes and split on ";" and ";" in loops?

我正在处理大量 (1,983) 个 CSV 文件。 Whosebug 上的帖子说列表更容易使用,所以我以这种方式处理了我的任务。我已经阅读了 CSV 并完成了任务的第一部分:应用程序的最大并发用户数是多少? (A:203) 这是代码:

# get a list of the files
        files <- list.files("my_path_here",pattern="*.CSV$", recursive = TRUE, full.names=TRUE)
#read in the csv's and store them as a list of dataframes
 tables <- lapply(files, read.csv)
 #store the counts of the number of users here
 counts<-rep(NA,length(tables))
 #loop thru the files to find the count and store that value
     for (i in 1:length(files)) {          
           counts[i] <- length(tables[[i]][[2]])      
                 }
#what's the largest number?
max(counts)
#203

任务的第二部分是显示每个文件的每个标题的数量。每个文件的内容将是这样的:

         compute_0001                   compute_0002
[1] 3/26/2015 6:00:00       Business System Manager;Lead CoPath Analyst                      
[2]                 Regional Histotechnologist;Hist Tech - Ht                        
[3]                 Regional Histotechnologist;Tissue Tech                           
[4]                 SDX Histotechnologist;Histology Tech                             
[5]                 SDX Histotechnologist;Histology Tech                             
[6]                 Regional Histotechnologist;Lab Asst II Histology                 
[7]                 CytoPrep Tech;Histo Tech - Ht                                    
[8]                 Regional Histotechnologist;Tissue Tech                           
[9]                 Histology Supervisor;Supv Reg Lab Unit                           
[10]                Histotech/FC Tech/PA/Diener;Pathology Tissue Technician;;CONTRACT

文件与文件的不同之处在于 compute_0001 中的时间戳、文件名和用户数(即文件长度)。 我的方法是尝试这个:

>col2 <- sapply(tables,summary, maxsum=300) # gives me a list of 1983 elements that is 23.6Mb

(我注意到在对文件执行 summary() 时我会得到这样的结果 - 这就是我尝试它的原因)

>col2[[1]]
    compute_0001                                compute_0002
1] Business System Manager;Lead CoPath Analyst                  :1       
 [2] Regional Histotechnologist;Hist Tech - Ht                  :1         
 [3] Regional Histotechnologist;Tissue Tech                     :1         
 [4] SDX Histotechnologist;Histology Tech                       :1         
 [5] SDX Histotechnologist;Histology Tech                       :1         
 [6] Regional Histotechnologist;Lab Asst II Histology           :2         
 [7] CytoPrep Tech;Histo Tech - Ht                              :4         
 [8] Regional Histotechnologist;Tissue Tech             :1                        
 [9 Histotech/FC Tech/PA/Diener;Pathology Tissue Technician;;CONTRACT :1

以上其实是很多不同的人。就我的目的而言,[2]、[3]、[6] 和 [8] 是相同的标题(即使“;”之后的内容不同。事实是甚至 [4] 和 [5] 也可以被认为与 [2,3,6,8] 相同)。

“:1”(或通常为“:#”)是在特定时间拥有该标题的用户数。我希望抓住那个角色,将其变成数字并将它们相加以获得每个文件的每个标题的用户数。每个文件都是在特定日期时间的观察结果。

我试过这样的事情:

>for (s in 1:length(col2)) {
>split <- strsplit(col2[[s]][,2], ":")
>#... make it numeric so I can do addition with it
>num <- as.numeric(split[[s]][2])
>#... and put it in the correct df
>tables[[s]]$count <- num

# After dealing with the ":" I was going to handle splitting on the first ";" 
>}

但我无法让循​​环迭代超过一次或超过 col2 的第一个元素。

更有经验的用户提出了这样的建议:

>strsplit(x = as.character(compute2[[s]]),split=";",fixed=TRUE)

He said "However this results in a messy list also, since there are multiple ";" in some lines.What I would #suggest is use grep() with a regex that returns the text before the first ";"- use that使用 sapply(compute2,grep()) 然后你可以 运行 sapply(??,table) 在 returned 列表上计算职位名称。

我不想进入正则表达式,但按照他的建议,我尝试了:

>for (s in 1:length(tables)){
>+ split <- strsplit(x = >as.character(compute2[[s]]),split=";",fixed=TRUE)
>+ }

split 是一个只有 122 的列表,不够长,所以它也没有遍历循环。所以,我想我会跳过循环并尝试:

>title_split<- sapply(compute2, strsplit, x = as.character(compute2[[1]]),split=";",fixed=TRUE)

但这给了我 50 多个警告和一个包含 105,000 多个元素且大小为 20.2Mb 的矩阵。

就像我说的,我不想冒险进入正则表达式的世界,因为我认为我应该能够首先拆分“:”,然后是“;”的第一个。 return “;”之前的字符串。我只是不确定循环失败的原因。

我最终想要的是一个 table,显示每个文件(其中表示在特定日期时间的观察)。我对方法非常不可知,所以如果我必须通过正则表达式来做,那就这样吧。

抱歉冗长 post 但我怀疑我的部分问题(除了对 Whosebug、R 和不了解正则表达式之外)是我不精通列表操作而且我希望你有上下文。

非常感谢阅读。

您的数据不容易重现,因此我创建了一个简单的虚假数据列表,希望能抓住您数据的本质。

列出假数据框:

string1  = "53 Regional histotechnologist;text2 - more text" 
string2  = "54 Regional histotechnologist;text2 - more text" 
string3  = "CytoPrep Tech;text2 - more text"

tables = list(df1=data.frame(compute=c(string1, string2, string3)), 
              df2=data.frame(compute=c(string1, string2, string3)))

计算每个数据框中的行数:

counts = sapply(tables, nrow)

添加一个从计算列中提取职务的列。正则表达式模式跳过零个或多个数字字符 ([0-9]*),后跟零个或一个 space 字符 (?),然后捕获所有内容,但不包括第一个 [=28] =](([^;]*);) 然后跳过 semi-colon (.*) 之后的每个字符。

tables = sapply(names(tables), function(df) {
  cbind(tables[[df]], title=gsub("[0-9]* ?([^;]*);.*", "\1", tables[[df]][,"compute"]))
}, simplify=FALSE)


tables

$df1
                                          compute                      title
1 53 Regional histotechnologist;text2 - more text Regional histotechnologist
2 54 Regional histotechnologist;text2 - more text Regional histotechnologist
3                 CytoPrep Tech;text2 - more text              CytoPrep Tech

$df2
                                          compute                      title
1 53 Regional histotechnologist;text2 - more text Regional histotechnologist
2 54 Regional histotechnologist;text2 - more text Regional histotechnologist
3                 CytoPrep Tech;text2 - more text              CytoPrep Tech

在 table 秒内对每个数据帧的每个标题进行 table 计数:

title.table.list = lapply(tables, function(df) table(df$title))

title.table.list

$df1

CytoPrep Tech Regional histotechnologist 
            1                          2 

$df2

CytoPrep Tech Regional histotechnologist 
            1                          2