我有data.frame
mapping
,其中包含路径和地图。
我还有另一个data.frame
DATA
,其中包含原始路径和值。
编辑:路径可能包含两个或更多组件:例如“A> C”或“A> C> B”
set.seed(24);
DATA <- data.frame(
path=paste0(sample(LETTERS[1:3], 25, replace=TRUE), ">", sample(LETTERS[1:3], 25, replace=TRUE)),
value=rnorm(25)
)
mapping <- data.frame(path=c("A","B","C"), map=c("X","Y","Z"))
lapply(mapping, function (x) {
for (i in 1:nrow(DATA)) {
DATA$path[i] <- gsub(as.character(x["path"]),as.character(x["map"]),as.character(DATA$path[i]))
}
})
我正在尝试将DATA
中的路径替换为mapping
中的地图值,但这对我来说似乎不起作用。
“A&gt; C”将转换为“X&gt; Z”。
我知道for R
中的for循环并不好,但我想不出另一种编码方式。我正在使用的数据大小为DATA
中的6米行和mapping
中的16k行。
对数据的澄清:虽然路径现在由字母(ABC)组成,但实际路径实际上是域名。路径中的步数也不固定为2,可以是任意数字。
答案 0 :(得分:5)
您可以使用chartr
DATA$path <- chartr('ABC', 'XYZ', DATA$path)
或者,如果我们使用来自&#39;映射&#39;
的数据 DATA$path <- chartr(paste(mapping$path, collapse=''),
paste(mapping$map, collapse=''), DATA$path)
或使用gsubfn
library(gsubfn)
pat <- paste0('[', paste(mapping$path, collapse=''),']')
indx <- setNames(as.character(mapping$map), mapping$path)
gsubfn(pat, as.list(indx), as.character(DATA$path))
或基于@ smci评论
的base R
选项
vapply(strsplit(as.character(DATA$path), '>'), function(x)
paste(indx[x], collapse=">"), character(1L))
答案 1 :(得分:2)
使用data.table
(1.9.5+
),特别建议您提供数据大小的b / c。
library(data.table)
setDT(DATA); setDT(mapping)
DATA[,paste0("path",1:2):=tstrsplit(path,split=">")]
setkey(DATA,path1)[mapping,new.path1:=i.map]
setkey(DATA,path2)[mapping,new.path2:=i.map]
DATA[,new.path:=paste0(new.path1,">",new.path2)]
如果你想摆脱额外的列:
DATA[,paste0(c("","","new.","new."),"path",rep(1:2,2)):=NULL]
如果您只想覆盖path
,请在最后一行的LHS上使用path
,而不是new.path
。
这也可以写得更简洁:
library(data.table)
setDT(mapping)
setkey(setkey(setDT(DATA)[,paste0("path",1:2):=tstrsplit(path,split=">")
],path1)[mapping,new.path1:=i.map],path2
)[mapping,new.path:=paste0(new.path1,">",i.map)]
答案 2 :(得分:0)
我认为您使用了错误的申请。
mapply允许你使用函数的两个参数,这里是路径和地图。请注意,在mapply中,参数FUN首先出现。您也不需要逐行执行此操作,您可以立即执行整个列。最后,在应用中,变量不像在for循环中那样更新,因此您需要在.GlobalEnv中分配它们。您可以通过显式调用assign()或使用&lt;&lt; - 将它们放在堆栈中找到它们的第一个位置来完成此操作。在这种情况下,这将返回.GlobalEnv。
如上所述定义映射和DATA之后,请尝试此操作。
#ifdef A_STATE
#import "a.h"
#else
#import "b.h"
#endif
请注意,对隐形的调用会抑制mapply的输出。
如果你真的想使用lapply,你可以。但是你需要转置映射。你可以这样做,但它会被转换为矩阵,所以你必须将其转换回来。然后,您可以使用&lt;&lt; - 并且不使用上面的for循环来获取此代码:
head(DATA)
invisible(mapply( function (x,y) {
DATA$path <<- gsub(x,y,DATA$path)
},mapping$path, mapping$map))
head(DATA)
感谢分享,我学到了很多回答这个问题。