使用一个键清洗对应的两个列中的数据

Using a key to clean data in two corresponding columns

我有一个大型数据框(600 万行,20 列),其中一列中的数据对应于另一列中的数据。我创建了一个键,现在我想用它来修复具有错误值的行。举个小例子:

key = data.frame(animal = c('dog', 'cat', 'bird'), 
                  sound = c('bark', 'meow', 'chirp'))

数据框如下所示(减去其他数据列):

 df = data.frame(id = c(1, 2, 3, 4),
                     animal = c('dog', 'cat', 'bird', 'cat'), 
                     sound = c('meow', 'bark', 'chirp', 'chirp'))

我发誓我以前做过这个但是不记得我的解决方案了。有什么想法吗?

使用dplyr。如果你想根据动物固定声音,

library(dplyr)
df <- df %>% 
  mutate(sound = sapply(animal, function(x){key %>% filter(animal==x) %>% pull(sound)}))

应该可以解决问题。如果你想根据声音修复动物:

df <- df %>% 
  mutate(animal = sapply(sound, function(x){key %>% filter(sound==x) %>% pull(animal)}))

我不确定相对效率,但完全替换部分不正确的列更简单。它甚至可能不会花费您太多时间(因为无论如何您都必须查找值以确定 animal/sound 对不匹配)。

library(tidyverse)
df %>% select(-sound) %>% full_join(key, by = "animal")

对于 600 万行,您最好使用 data.table。如果将 dfkey 转换为数据表 (as.data.table()) 将花费一些 up-front 的计算时间,但可能会加快后续操作;您可以在 data.table 对象上使用 tidyverse 操作而无需进行任何进一步修改,但原生 data.table 操作可能更快:

library(data.table
dft <- as.data.table(df)
k <- as.data.table(key)
merge(dft[,-"sound"], k, by = "animal")

我懒得做任何基准测试(需要更大的例子才能衡量任何差异)。