【问题标题】:Given a column of keys, overwrite it with a column of strings based on a dictionary给定一列键,用基于字典的一列字符串覆盖它
【发布时间】:2019-02-05 16:59:30
【问题描述】:

我有以下两个数据框:

 n <- 15000
 key <- sample(1:10, 10)
 dictionary <- data.frame(key = key, value = LETTERS[1:10])

 target_df <- data.frame(code = sample(key, n, replace = TRUE))
 target_df$code[sample(seq_len(n), 10)] <- 0

我想用来自dictionary 的相应values 覆盖code。什么是有效的可读的方式来做到这一点?我用过

find_in_dictionary <- function(x) {
  y <- dictionary[match(x, dictionary[, 1]), 2]
}

target_df$code <- find_in_dictionary(target_df$code)
sum(is.na(target_df$code))

它似乎工作正常,并且可以正确处理不匹配的情况。你有更好的建议吗?

【问题讨论】:

  • @DeltalV:如果答案对您有用,请考虑投票或接受答案:) 谢谢

标签: r function dictionary dataframe


【解决方案1】:

你需要使用dplyrleft_join函数。这是一个 SQL 连接。

library(dplyr)
library(tidyr)
n <- 15000
key <- sample(1:10, 10)
dictionary <- data.frame(key = key, value = LETTERS[1:10])

target_df <- data.frame(code = sample(key, n, replace = TRUE))
target_df$code[sample(seq_len(n), 10)] <- 0

target_df %>%
  arrange(code) %>%
  left_join(dictionary, by = c("code"="key")) %>%
  drop_na(.)-> final_df

head(final_df)
#>    code value
#> 11    1     I
#> 12    1     I
#> 13    1     I
#> 14    1     I
#> 15    1     I
#> 16    1     I

# final_df without 'order'
target_df %>%
  left_join(dictionary, by = c("code"="key")) %>%
  drop_na(.) %>%
  head(.)
#>   code value
#> 1    6     A
#> 2    6     A
#> 3    8     D
#> 4    7     F
#> 5    8     D
#> 6    9     H

final_df %>%
  select(value) %>%
  head(.)
#>    value
#> 11     I
#> 12     I
#> 13     I
#> 14     I
#> 15     I
#> 16     I

您也可以使用data.table 包来获得类似的结果。 SO对此有很多疑问。

由 reprex 包 (v0.2.0) 于 2018-08-30 创建

【讨论】:

  • 您错过了target_df$code[sample(seq_len(n), 10)] &lt;- 0 部分(我用来确保解决方案正确处理不匹配的情况)。但是我将它添加到您的代码中,它仍然有效。干得好!
  • @Suhas Hedge:你能检查一下你的输出吗?出了点问题。请使用dictionary data.frame 验证您的映射。
  • @Suhas Hedge:如果我错了,请随时纠正我!
  • @SaurabhChauhan 我在发布答案后也看到了。我认为这就是这些值的排序方式。我没有在我的 dplyr 管道中使用明确的排序。不过还是得去看看
  • 我错过了target_df$code[sample(seq_len(n), 10)] &lt;- 0
【解决方案2】:

使用sqldf: 映射keyvalue,根据keydata.frame 中查看left join

在运行此之前,您只需更改 colnamestarget_df

colnames(target_df)<-c("key")
head(sqldf("Select t.key,d.value from target_df t LEFT JOIN dictionary d on (t.key=d.key)"))

输出:

   key value
1   1     I
2   3     B
3   1     I
4   5     C
5   2     F
6   7     E

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 2017-07-20
    • 1970-01-01
    • 2021-07-01
    • 1970-01-01
    相关资源
    最近更新 更多