从data.frame创建一个查找表

时间:2015-04-28 17:41:17

标签: r hash

我有一个data.frame,在所有列中只有一个唯一的非NA值,但只有一个,只有NA

data <- data.frame(A = c("egg", "egg"), B = c(NA, "bacon"), C = c("ham", "ham"), D = c(NA, NA))

如何使用它来创建下表中的查找表?

lookup <- make_lookup(key=unique_values(data), value=names(data))
lookup[["egg"]] # returns "A"
lookup[["bacon"]] # returns "B"
lookup[["ham"]] # returns "C"
lookup[["NA"]] # returns "D"

修改

根据弗兰克在下面的回答,我试图让我的查找表引用多个值。

keys <- lapply(data, function(x) if(is.factor(x)) levels(x) else "bacon")
vals <- names(data)
  

$A
[1] "egg"

$B
[1] "bacon"

$C
[1] "ham"

$D
[1] "bacon"
  

瓦尔斯

[1] "A" "B" "C" "D"
  

tapply(vals,keys,c)

Error in tapply(vals, keys, c) : arguments must have same length

1 个答案:

答案 0 :(得分:5)

这是一种方法。查找是一个向量:

keys <- sapply(data,function(x)if(is.factor(x))levels(x)else "NA")
vals <- names(data)

lookup <- setNames(vals,keys)

我已将NA替换为"NA",因为我无法弄清楚如何使用前者。

语法lookup[["egg"]]有效,但也有lookup["egg"]。反向查找为rlookup <- keys,可以通过相同的方式访问:rlookup["A"]

对于具有多个值的键。如果键可能映射到值向量,请使用

lookup <- tapply(vals,keys,c)

例如,如上所述,使用keys <- sapply(data,function(x)if(is.factor(x))levels(x)else "bacon")vals进行此操作(如下面的OP评论)。现在查找是一个列表,因此只能使用双括号访问:lookup[["bacon"]]。反向查找与以前一样。

适用于一般列类。如果data的列不是所有因素,则需要修改或推广if / else条件。以下是来自评论的@ akrun通用解决方案的一个版本:

keys <- sapply(data,function(x)c(unique(as.character(x)[!is.na(x)]),"NA")[1])