【问题标题】:R combine data.frame with varying length in a columnR在列中组合具有不同长度的data.frame
【发布时间】:2012-08-01 08:04:37
【问题描述】:

我有一个问题,我想道歉,如果这个问题已经讨论过,即使我检查了旧帖子。

我有一个包含 2 列的 data.frame,第二列可以包含多个标识符,但数量可能会有所不同。在另一个 data.frame 中,标识符对应于另一个标识符。

df.1  

color   identifier
blue    A1, B2, C3, C4 
yellow  B2, C4, C6
green   A3

df.2

A1 Mercedes
A3 BMW
B2 Porsche
C3 Toyota
C4 Hundai
C5 Volkswagen
C6 Peugeot    

我想要的是这样的data.frame:

df.3

color   identifier        identifier2
blue    A1, B2, C3, C4    Mercedes, Porsche, Toyota, Hundai 
yellow  B2, C4, C6        Porsche, Hundai, Peugeot
green   A3                BMW

一个data.frame,其中包含标识符以及第二个data.frame的标识符。

我尝试使用 apply 和 stack 和 unstack,但我一点也不成功。

你有什么建议吗?

【问题讨论】:

    标签: r merge dataframe


    【解决方案1】:

    这是另一个解决方案,使用strsplit

    # The data
    df.1  = read.table(header=TRUE, text="
    color   identifier
    blue    'A1, B2, C3, C4'
    yellow  'B2, C4, C6'
    green   'A3'", stringsAsFactors = FALSE)
    
    df.2 = read.table(header=FALSE, text="
    A1 Mercedes
    A3 BMW
    B2 Porsche
    C3 Toyota
    C4 Hundai
    C5 Volkswagen
    C6 Peugeot", stringsAsFactors=FALSE)
    names(df.2) = c("identifier", "car")
    
    df.1$identifier = strsplit(df.1$identifier, split=", ")
    df.1$identifier1 = lapply(1:nrow(df.1), 
             function(x) df.2[which(df.2$identifier %in% df.1$identifier[[x]]), 2])
    df.1
    #    color     identifier                       identifier1
    # 1   blue A1, B2, C3, C4 Mercedes, Porsche, Toyota, Hundai
    # 2 yellow     B2, C4, C6          Porsche, Hundai, Peugeot
    # 3  green             A3                               BMW
    

    请注意,identifieridentifier1 现在是您的data.frame 中的列表。我个人觉得这在以后更容易使用。

    str(df.1)
    # 'data.frame':  3 obs. of  3 variables:
    #   $ color      : chr  "blue" "yellow" "green"
    # $ identifier :List of 3
    #  ..$ : chr  "A1" "B2" "C3" "C4"
    #  ..$ : chr  "B2" "C4" "C6"
    #  ..$ : chr "A3"
    # $ identifier1:List of 3
    #  ..$ : chr  "Mercedes" "Porsche" "Toyota" "Hundai"
    #  ..$ : chr  "Porsche" "Hundai" "Peugeot"
    #  ..$ : chr "BMW"
    

    如果有剩余的空格,您可能需要修改strsplit,但它适用于此示例数据。此外,要使strsplit 工作,数据需要处于as.character 模式(因此我在读取数据时使用stringsAsFactors)。

    更新:write.table()

    确实更喜欢将数据保存在列表中,以防我想做进一步的分析。但是,如果数据完整或仅用于输出目的,您可能需要执行以下操作:

    df.3 = df.1
    df.3$identifier = sapply(df.3$identifier, paste0, collapse=", ")
    df.3$identifier1 = sapply(df.3$identifier1, paste0, collapse=", ")
    

    这将允许您使用write.table,因为identifieridentifier1 现在处于character 模式而不是list

    【讨论】:

    • 但是使用 data.frame 中的列表真的更容易吗?例如。如果我尝试编写表格,我会收到错误消息。
    【解决方案2】:

    可能最简单的方法是使用带有gsub 的正则表达式来进行替换。

    重新创建您的数据:

    df1 <- read.table(text="
    color   identifier
    blue    'A1, B2, C3, C4'
    yellow  'B2, C4, C6'
    green   A3
    ", header=TRUE)
    
    
    df2 <- read.table(text="
    A1 Mercedes
    A3 BMW
    B2 Porsche
    C3 Toyota
    C4 Hundai
    C5 Volkswagen
    C6 Peugeot 
    ", header=FALSE)
    

    现在您必须遍历颜色查找 (df2) 的每个元素并在 df1 中进行替换:

    for (i in seq_len(nrow(df2))){
      df1$identifier <- gsub(df2[i, 1], df2[i, 2], df1$identifier)
    }
    

    结果:

    df1
       color                        identifier
    1   blue Mercedes, Porsche, Toyota, Hundai
    2 yellow          Porsche, Hundai, Peugeot
    3  green                               BMW
    

    【讨论】:

    • 感谢安德烈的建议。
    猜你喜欢
    • 1970-01-01
    • 2020-04-09
    • 2012-02-03
    • 2018-07-26
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 1970-01-01
    相关资源
    最近更新 更多