R将列中具有不同长度的data.frame组合在一起

时间:2012-08-01 08:04:37

标签: r merge dataframe

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

我有一个包含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 and unstack,但我根本没有成功。

你有什么建议吗?

2 个答案:

答案 0 :(得分:2)

这是另一种解决方案,使用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

答案 1 :(得分:1)

最简单的方法可能是使用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