有条件地填充空单元格

时间:2019-08-15 13:42:10

标签: r

我有一个命名向量,但缺少一些值:

Map<Range<Integer>, Character> rangeToGrade = Map.of(
   Range.between(90, 100), 'A',
   Range.between(80, 90), 'B'
   //... the rest
);

int mark = 50;
char grade = rangeToGrade.entrySet().stream()
    .filter(e -> e.getKey().contains(mark))
    .map(Map.Entry::getValue)
    .findFirst()
    .orElse('?'); // or throw an exception

还有第二个数据框,它反映了层次结构的命名结构(例如A是AA,AB和AC的上级)

x = c(99, 88, 1, 2, 3, NA, NA)
names(x) = c("A", "C", "AA", "AB", "AC", "AD", "CA")

如果x中缺少一个值,我想用填充器的上级填充它。这样结果就是

filler = data.frame(super = c("A", "A", "A", "A", "C"), sub = c("AA", "AB", "AC", "AD", "CA"))

有人在没有遍历每种可能性的情况下有任何聪明的方法吗?

2 个答案:

答案 0 :(得分:2)

我们可以基于NA元素创建逻辑向量('i1'),使用match获取'filler'中匹配元素的索引,然后进行赋值

i1 <- is.na(x)
x[i1] <- x[match(filler$super[match(names(x[i1]), filler$sub)], names(x))] 
as.vector(x)
#[1] 99 88  1  2  3 99 88

答案 1 :(得分:0)

由于x是命名向量,我们可以将其转换为数据帧(enframe),然后进行联接,将NA的值替换为相应的value,如果需要,再次将其转换为向量。 (deframe

library(dplyr)
library(tibble)

enframe(x) %>%
  left_join(filler, by = c("name" = "sub")) %>%
   mutate(value = if_else(is.na(value), value[match(super, name)], value)) %>%
   select(-super) %>%
   deframe()

# A  C AA AB AC AD CA 
#99 88  1  2  3 99 88