作者Wush978 (拒看低质媒体)
看板Statistics
标题Re: [程式] R 字串比对问题
时间Mon Mar 25 18:51:43 2013
※ 引述《windguide (夜很深)》之铭言:
: ------------------------------------------------------------------------
: [软体程式类别]:
: 我尽量描述我的资料格式,希望大家可以了解
: Old Data New Data
: name Description name Description
: Tom John happy hungry energy Kate greedy,lazy,evil
: Mary pretty cute funny Tom happy,kind
: Kate greedy lazy John hungry,energy,angry,crazy
: Cindy sunny Mary pretty,cute
: Jack nice,stupid
: Alan funny,shy,stupid
谢谢你提供的资料范例
: 两栏之间是以TAB作分隔
: 在name栏中 旧资料与新资料的差异是在同一列中,旧资料会同时有两个名字
: 新资料则是拆开成两列,且新资料会有多的人名
: 在 Description栏中,旧资料是以空白作分隔,新资料是逗点;且同一人名新资料
: 会多或少一些描述
: 现在我的目标是产生一个新档案
: 以新的资料人名为主。旧资料有,新资料没有的人名,不要。
: 以新资料的人名,去比较新与旧的描述,只要新的描述。旧的有,新的没有也不要
: 并且以空白作分隔
: 以上述例子,结果会变成
: name Discription
: Kate evil
: Tom kind
: John angry crazy
: Mary
: Jack nice stupid
: Alan funny shy stupid
: 我现在的想法是说 把新旧资料设为matrix
: 将先将旧资料与新资料作match,找出旧资料的index,
: 再依此index对相对应的Discription作处理
: match(new[,1],old[,1])
: 但是此时会产生一个问题,就是在旧资料的 Tom John 这笔资料
: 无法被新资料match到,所以我猜match是精准比对?
: 有无办法变成部分比对或模糊比对?或者有更好的方式
: 再来就是Discription的部分,我是想找到index後,将相对应的新旧资料
: 再做一次比对,然後取代回新资料。可是这种类似取差集的的过程,有没有
: 适当的函式可以操作。另外,我也不太懂要如何将资料matrix中的元素
: 以逗号和空白拆开,让我可以做比对
: 不知各位有没有其他的想法,文长抱歉
: [程式范例]:
: 虽然张贴程式很可怕,但基本上有些程式还是要张贴才能解决
: -----------------------------------------------------------------------------
考虑到你的资料的特性:
- 基本上会大量使用name(key) --> description(value)的操作
- description项目的栏位长度不定
我会建议用以下的R的资料结构来处理这个问题
old_data <- list()
old_data[["Kate"]] <- c("greedy","lazy")
...
old_data[["Mary"]] <- c("pretty", "cute", "funny")
new_data <- list()
new_data[["Kate"]] <- c("greedy", "lazy", "evil")
...
new_data[["Mary"]] <- c("pretty", "cute")
当转换成这样的资料结构之後,你可以使用
setdiff(names(new_data), names(old_data))
来看new_data中多出来的人名
而个别人名的比对可以用
setdiff( new_data[["Kate"]], old_data[["Kate"]] ) 来看new_data比old_data多的
属性
所以问题只剩下如何把你现有的资料转换成上述的资料结构了
假设你用read.csv或是其他函数把你的原始资料读入R
old_data.raw <- read.csv( old_data.filename, stringsAsFactors = FALSE)
如果没有其他问题(如格式、encoding...)
你应该会得到一个data.frame
old_data.raw
然後一个row一个row的把资料塞到old_data中
name <- strsplit(old_data.raw$name[i], " ", fixed=TRUE)
for(i in 1:nrow(old_data.raw)) {
for(j in 1:length(name[[i]]) {
old_data[[name[[i]][j]]] <- strsplit(old_data.raw$Discription[i],
" ", fixed=TRUE)[[1]]
}
}
new_data的处理方式类似,只是要替换split character
以上方式假设你没有效能问题(例如资料过大,导致无法读入记忆体...)
另外如果你要考虑不完全精确的比对,可以看看pmatch这个函数
请参考
--
欢迎加入 Taiwan R User Group :
http://www.facebook.com/Tw.R.User
我们每周一都有在「政大公企中心(台北市金华街187号)西楼WB05」
举办Machine Learning / Data Mining Monday:
报名
http://www.meetup.com/Taiwan-R/
聚会影片
https://www.youtube.com/user/TWuseRGroup
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 118.231.66.185
※ 编辑: Wush978 来自: 118.231.66.185 (03/25 18:53)
1F:推 windguide:谢谢W大提供的想法,我来试试看,感谢 03/26 10:54
2F:→ MIZUYAMA:这个问题好复杂= = 03/28 22:23