在我的具体情况中,我有两个数据框:
> a
column
1 red apple
2 red car
3 yellow train
4 random
5 random string
6 blue water
7 thing
> map
x y
1 red color
2 blue color
3 yellow color
4 random other
5 thing other
我想要的结果是:
> a
column
1 color
2 color
3 color
4 other
5 other
6 color
7 other
我知道这篇文章给出了使用merge Replacing values in data frame column using another data frame的示例。但就我而言,这方面略有不同:
我如何写一些能够有效地为我做这件事的东西?实际上两个数据框架更大。 A是30k行,地图是30x2
编辑:子字符串可以从“列”开始,而不一定是第一个字
答案 0 :(得分:1)
可重复的例子:
a <- data.frame(column=c('red apple', 'red car', 'yellow train', 'random', 'random string', 'blue water', 'thing'), stringsAsFactors=F)
map <- data.frame(x=c('red', 'blue', 'yellow', 'random'), y=c('color', 'color', 'color', 'other'))
有几个选择。我能想到两个(我相信还有更多),我会告诉你如何计时他们来比较他们的表现。您可能必须尝试自己的特定数据的时间,因为哪种方法最快可能会改变,具体取决于例如map$x
与a
的比较大小,或a
或map
的大小。
strsplit
来抓取第一个单词。pmatch
在这里不会真正起作用,因为你试图将更长的字符串与更短的字符串匹配。data.table
是快速处理大数据的常用方法。我认为正则表达式可能是这里的限制因素,所以我不确定你会以这种方式加速。
# rbenchmark library to compare times
library(rbenchmark)
benchmark(firstword={
# extract first word; match exactly against the map
# probably fastest; but "dumbest" unless you know the first word
# is always the match
firstword <- vapply(a$column, function (x) strsplit(x, ' ')[[1]][1], '', USE.NAMES=F)
out.firstword <<- map$y[match(firstword, map$x)]
},
regex = {
# regex option: find the matching word, then use `match`
# will have problems if any of map$x has regex special characters.
regex <- sprintf('^.*\\b(%s)\\b.*$', paste(map$x, collapse='|')) # ^.*\b(red|blue|yellow|random)\b.*$
out.regex <- map$y[match(gsub(regex, '\\1', a$column), map$x)]
},
replications=100)
# check we at least agree on the output and get the expected output
all.equal(out.regex, out.firstword)
all.equal(as.character(out.regex), c('color', 'color', 'color', 'other', 'other', 'color', NA))
请注意,如果您对大数据进行基准测试,则可能希望减少重复次数!你不想坐等几年...... 另请注意,最后一行返回“NA”而不是其他行,因为字符串“thing”与地图中的任何内容都不匹配。
返回
test replications elapsed relative user.self sys.self user.child sys.child
1 firstword 100 0.010 1.111 0 0 0 0
2 regex 100 0.009 1.000 0 0 0 0
因此,对于您的特定示例数据,正则表达式方法更快 - 但如前所述,它将全部取决于您的特定数据[此示例的性质是数据集很小,所以一切都快于其他]所以你的里程可能会有所不同。
答案 1 :(得分:0)
已编辑:反映来自mathematical.coffee的评论 已编辑:在匹配时切换订单
首先,我们需要清理数据帧,使其与预期的字段匹配。所以像a$column1 <- gsub("red.+","red",a$column)
之类的东西,然后冲洗并重复其余部分。我不知道如何匹配&#34;其他&#34;类别......必须手动完成。
一旦你有了正确的名字,match
就可以在这里运作良好:
您应该使用以下内容获取所需的结果:map$y[match(a$column1,map$x)]
。内部部分进行匹配,map$y
部分为您提供所需的属性。