【问题标题】:In R, how should I compare two data tables and give the desired output as shown below?在 R 中,我应该如何比较两个数据表并给出所需的输出,如下所示?
【发布时间】:2017-02-22 20:32:21
【问题描述】:

这些只是一个巨大数据框的样本

Sample1
                       col1                            col2
1      123001 124003 125699 348348 3493493 1230404 99930202
2 29238822 293831232 992922 348348 3493493 1230404 99930202

Sample1 在每个单元格中都有一组数字(以空格分隔)

Sample2
        col1  col2
1     123001   CAT
2   99930202   PIG
3     124003   ODG
4    1230404 CHAIN
5   29238822   BAT
6  293831232 MOUSE
7    3493493  KIWI
8     125699   JIN
9     992922 ANIME
10    348348  UPPE

如果Sample2表中的数字存在匹配,则应该将sample2表中Col2中的对应值拉起。

最终期望的输出如下。

Output
                   col1                                col2            col3
1      123001 124003 125699 348348 3493493 1230404 99930202     CAT ODG JIN
2 29238822 293831232 992922 348348 3493493 1230404 99930202 BAT MOUSE ANIME
                 col4
1 UPPE KIWI CHAIN PIG
2 UPPE KIWI CHAIN PIG

我尝试使用不同的方法合并、连接、sqldf,但无法获得我的输出。有人可以帮忙吗?

【问题讨论】:

  • 您应该生成分配列名的数据框。另外,请详细说明您打算做什么。此外,我建议您输出数据框 Sample1 和 Sample 2。它可以帮助您了解它们的外观并正确地构建您的问题。
  • 对不起,修改了问题,谢谢!
  • 分隔符是空格
  • @d.b 如果您觉得这回答了问题,请照此发布。

标签: r data.table


【解决方案1】:

这个问题在 SO 上可能有重复,但我没有花太多时间在谷歌上搜索。

您可以使用data.table 包中的meltdcast 尝试此解决方案:

molten <- melt(Sample1, measure.vars = c("col1", "col2"))
splitted <- molten[, strsplit(value, " "), by = .(rowid(variable), variable)]
splitted[, V1  := as.integer(V1)]
joined <- Sample2[splitted, on = c(id = "V1")]
dcast(joined, rowid ~ variable, paste, collapse = " ", value.var = c("id", "text"))
#   rowid                   id_col1                         id_col2       text_col1
#1:     1      123001 124003 125699 348348 3493493 1230404 99930202     CAT ODG JIN
#2:     2 29238822 293831232 992922 348348 3493493 1230404 99930202 BAT MOUSE ANIME
#             text_col2
#1: UPPE KIWI CHAIN PIG
#2: UPPE KIWI CHAIN PIG

这种方法与Sample1 中的列数无关,也与每个单元格中数字集的大小无关。

数据

Sample1 <-
structure(list(col1 = c("123001 124003 125699", "29238822 293831232 992922"
), col2 = c("348348 3493493 1230404 99930202", "348348 3493493 1230404 99930202"
)), .Names = c("col1", "col2"), row.names = c(NA, -2L), class = c("data.table", 
"data.frame"))
Sample2 <-
structure(list(id = c(123001L, 99930202L, 124003L, 1230404L, 
29238822L, 293831232L, 3493493L, 125699L, 992922L, 348348L), 
    text = c("CAT", "PIG", "ODG", "CHAIN", "BAT", "MOUSE", "KIWI", 
    "JIN", "ANIME", "UPPE")), .Names = c("id", "text"), row.names = c(NA, 
-10L), class = c("data.table", "data.frame"))

【讨论】:

    【解决方案2】:
    sample1$col3 = sapply(strsplit(sample1$col1, " "), function(a)
                      paste(sample2$text[match(a, sample2$id)], collapse = " "))
    

    如果你想在多个列上使用它,那么为我们上面所做的创建一个函数,然后将它应用到所需的列上。

    myf = function(x){
        return(sapply(strsplit(x, " "), function(a)
            paste(sample2$text[match(a, sample2$id)], collapse = " ")))
    }
    
    sapply(sample1, myf)
    

    数据

    sample1 = structure(list(col1 = c("123001 124003 125699", "29238822 293831232 992922"
            ), col2 = c("348348 3493493 1230404 99930202", "348348 3493493 1230404 99930202"
            ), col3 = c("CAT ODG JIN", "BAT MOUSE ANIME")), .Names = c("col1", 
            "col2", "col3"), row.names = c(NA, -2L), class = "data.frame")
    
    sample2 = structure(list(id = c(123001L, 99930202L, 124003L, 1230404L, 
            29238822L, 293831232L, 3493493L, 125699L, 992922L, 348348L), 
                text = c("CAT", "PIG", "ODG", "CHAIN", "BAT", "MOUSE", "KIWI", 
                "JIN", "ANIME", "UPPE")), .Names = c("id", "text"), row.names = c(NA, 
            -10L), class = "data.frame")
    

    【讨论】:

    • 这是一个很好的解决方案,它使用带有基础 R 的单行来转换一列。您将如何应用此解决方案来转换具有多列(超过 OP 中的 2 列)的数据框?
    猜你喜欢
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多