我有一个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
答案 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])