我有一个数据框,其中一列是名称。在后面的分析阶段,我需要通过此名称列与其他数据合并,并且有一些名称因来源而异。我想使用名称 - >清除名称的哈希(地图)来清理我的名字。我发现了几个使用R列表作为哈希的引用(例如,this question on SE),但我无法弄清楚如何在向量中提取键时它们的值。例如,
> players=data.frame(names=c("Joe", "John", "Bob"), scores=c(9.8, 9.9, 8.8))
> xref = c("Bob"="Robert", "Fred Jr." = "Fred")
> players$names
[1] Joe John Bob
Levels: Bob Joe John
尽管players$names
给出了原始帧中的名称向量,但我需要相同的向量,只有xref
中出现的任何值都替换为它们的等效(查找)值;我想要的结果是向量Joe John Robert
。
我最接近的是:
> players$names %in% names(xref)
[1] FALSE FALSE TRUE
这正确地指出players$names
中的“密钥”(名称)中仅存在xref
中的“Bob”,但我无法弄清楚如何提取该名称的值并组合它与矢量中的其他名称根据需要不属于xref
。
注意:如果不完全清楚,我对R很新,所以如果我以错误的方式接近这个,我很乐意纠正,但我的核心问题基本上如上所述:我需要通过用已知替换替换一些传入值并保留所有其他值来清理R 中的一些传入数据;此外,原始>替换的地图应存储为数据(如xref),而不是代码。
答案 0 :(得分:4)
ifelse
是一个更直接的解决方案,在xref是命名向量而不是列表的情况下。
players <- data.frame(names=c("Joe", "John", "Bob"), scores=c(9.8, 9.9, 8.8), stringsAsFactors = FALSE)
xref <- c("Bob" = "Robert", "Fred Jr." = "Fred")
players$clean <- ifelse(is.na(xref[players$names]), players$names, xref[players$names])
players
结果
names scores clean
1 Joe 9.8 Joe
2 John 9.9 John
3 Bob 8.8 Robert
如果外部参照是一个列表,那么sapply
函数可用于进行条件查找
players <- data.frame(names=c("Joe", "John", "Bob"), scores=c(9.8, 9.9, 8.8))
xref <- list("Bob" = "Robert", "Fred Jr." = "Fred")
players$clean <- sapply(players$names, function(x) ifelse( x %in% names(xref), xref[x], as.vector(x)) )
players
结果
> players
names scores clean
1 Joe 9.8 Joe
2 John 9.9 John
3 Bob 8.8 Robert
答案 1 :(得分:2)
您可以使用所需的文本替换因子级别。这是一个循环xref
并进行替换的示例:
for (n in names(xref)) {
levels(players$names)[levels(players$names) == n ] <- xref[n]
}
players
## names scores
## 1 Joe 9.8
## 2 John 9.9
## 3 Robert 8.8
答案 2 :(得分:1)
替换因子水平的另一个例子。
allnames = levels(players$names)
levels(players$names)[ !is.na(xref[allnames]) ] = na.omit(xref[allnames])
players
# names scores
# 1 Joe 9.8
# 2 John 9.9
# 3 Robert 8.8
如果您进入了非常大的数据集,可以查看merge
函数或data.table
包。以下是联接的data.table
示例。
library(data.table)
players=data.table(names=c("Joe", "John", "Bob"), scores=c(9.8, 9.9, 8.8), key="names")
nms = data.table(names=names(xref),names2=xref, key="names")
out = nms[players]
out[is.na(names2),names2:=names]
out
# names names2 scores
# 1: Bob Robert 8.8
# 2: Joe Joe 9.8
# 3: John John 9.9
以下是merge
函数的类似示例。
players=data.frame(names=c("Joe", "John", "Bob"), scores=c(9.8, 9.9, 8.8))
nms = data.frame(names=names(xref),names2=xref,row.names=NULL)
merge(nms,players,all.y=TRUE)
# names names2 scores
# 1 Bob Robert 8.8
# 2 Joe <NA> 9.8
# 3 John <NA> 9.9