从Python到R-数据帧从字符串
我有一个Python的工作示例,它接受一个字符串,使用dict理解和正则表达式,最后从中生成一个数据帧:从Python到R-数据帧从字符串,python,r,regex,Python,R,Regex,我有一个Python的工作示例,它接受一个字符串,使用dict理解和正则表达式,最后从中生成一个数据帧: import re, pandas as pd junk = """total=7871MB;free=5711MB;used=2159MB;shared=0MB;buffers=304MB;cached=1059MB; free=71MB;total=5751MB;shared=3159MB;used=5MB;buffers=30MB;cached=1059MB; cached=1059
import re, pandas as pd
junk = """total=7871MB;free=5711MB;used=2159MB;shared=0MB;buffers=304MB;cached=1059MB;
free=71MB;total=5751MB;shared=3159MB;used=5MB;buffers=30MB;cached=1059MB;
cached=1059MB;total=5751MB;shared=3159MB;used=5MB;buffers=30MB;free=109MB;"""
rx = re.compile(r'(?P<key>\w+)=(?P<value>[^;]+)')
records = [{m.group('key'): m.group('value')
for m in rx.finditer(line)}
for line in junk.split("\n")]
df = pd.DataFrame(records)
print(df)
现在怎么。。。我可以在R做同样的事情吗?
我把lapply和regmatches弄得乱七八糟,但没用。此外,如果缺少值,我将如何执行此操作?A purrr选项:
图书馆咕噜声
'总数=7871MB;自由=5711MB;已使用=2159MB;共享=0MB;缓冲区=304MB;缓存=1059MB;
免费=71MB;总数=5751MB;共享=3159MB;已使用=5MB;缓冲区=30MB;缓存=1059MB;
缓存=1059MB;总数=5751MB;共享=3159MB;已使用=5MB;缓冲区=30MB;空闲=109MB;'%>%
strsplit'\n'%>%.[1]]%>%将行分隔为字符向量
strsplit';'%>%将每行分隔为键值对列表
mapstrsplit,'='%>%将键值对拆分为长度为2的子列表
maptranspose%>%将键值对列表翻转到键值列表
将_-dfr~set_-names.x[[2]],.x[[1]]将值的名称映射到键,并简化为数据帧
>一个tibble:3x6
>缓存的可用共享缓冲区总数
>
>17871MB 5711MB 2159MB 0MB 304MB 1059MB
>25751MB 71MB 5MB 3159MB 30MB 1059MB
>3 5751MB 109MB 5MB 3159MB 30MB 1059MB
或更以数据帧为中心的选项:
图书馆管理员
将文本放入数据框
数据_frametext='总计=7871MB;自由=5711MB;已使用=2159MB;共享=0MB;缓冲区=304MB;缓存=1059MB;
免费=71MB;总数=5751MB;共享=3159MB;已使用=5MB;缓冲区=30MB;缓存=1059MB;
缓存=1059MB;总数=5751MB;共享=3159MB;已使用=5MB;缓冲区=30MB;空闲=109MB;'%>%
sep_rowstext,sep='\n'>%将行分隔为单独的行
rowid_to_列的行'>%为每行添加索引以帮助以后扩展
单独的行文本,sep=';'%>%将每行分隔为键值对
filtertext!=%>%从多余的分号中删除额外的条目
separatetext,c'key',value%%>%将键和值分隔为列
spreadkey,值%>%重塑为宽格式
选择“行”下拉“行索引”列
>一个tibble:3x6
>缓存的可用共享缓冲区总数已使用
>
>1304MB 1059MB 5711MB 0MB 7871MB 2159MB
>2 30MB 1059MB 71MB 3159MB 5751MB 5MB
>3 30MB 1059MB 109MB 3159MB 5751MB 5MB
如果您想避免使用包,可以通过read.dcf进行破解,它读取Debian控制格式,如R包描述文件,这只是键值对。DCF使用:代替=和\n代替;,不过,您需要先做一点gsubing:
垃圾邮件[3,]5751MB 109MB 5MB 3159MB 30MB 1059MB
它返回一个矩阵,但格式良好,易于转换为正确的数据帧:
df缓存的可用共享缓冲区总数
>17871MB 5711MB 2159MB 0MB 304MB 1059MB
>25751MB 71MB 5MB 3159MB 30MB 1059MB
>3 5751MB 109MB 5MB 3159MB 30MB 1059MB
工作示例:
junk <- "total=7871MB;free=5711MB;used=2159MB;shared=0MB;buffers=304MB;cached=1059MB;
free=71MB;total=5751MB;shared=3159MB;used=5MB;buffers=30MB;cached=1059MB;
cached=1059MB;total=5751MB;shared=3159MB;used=5MB;buffers=30MB;free=109MB;"
names <- unique(strsplit(gsub("[(?\\n=\\d+MB;)]", " ", a, perl=TRUE), "(\\s+)")[[1]])
dataset <- read.table(text=gsub("[^(\\d+)]", " ", a, perl=TRUE), header = FALSE, col.names=names)
我知道这是可行的,但是你能在答案中解释一下吗?添加了很多评论。如果你穿过每一根管道,你也可以很容易地看到中间产品。这是如何工作的?您想添加一些解释吗?如果列的顺序一致,这种方法会起作用。因为它们不是,所以它是按位置而不是按标签读取数据,这会导致交换值,例如在free和total的第一行和第二行之间。
junk <- "total=7871MB;free=5711MB;used=2159MB;shared=0MB;buffers=304MB;cached=1059MB;
free=71MB;total=5751MB;shared=3159MB;used=5MB;buffers=30MB;cached=1059MB;
cached=1059MB;total=5751MB;shared=3159MB;used=5MB;buffers=30MB;free=109MB;"
names <- unique(strsplit(gsub("[(?\\n=\\d+MB;)]", " ", a, perl=TRUE), "(\\s+)")[[1]])
dataset <- read.table(text=gsub("[^(\\d+)]", " ", a, perl=TRUE), header = FALSE, col.names=names)