如何解析数据帧列表中的数百个 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
我正在处理大量 (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