基于列表(哈希)替换R中的向量值

时间:2014-03-09 22:40:36

标签: r

我有一个数据框,其中一列是名称。在后面的分析阶段,我需要通过此名称列与其他数据合并,并且有一些名称因来源而异。我想使用名称 - >清除名称的哈希(地图)来清理我的名字。我发现了几个使用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),而不是代码。

3 个答案:

答案 0 :(得分:4)

更新的答案:ifelse

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

如果外部参照是一个列表,那么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