2

我有一个小问题,在概念上似乎很容易,但我找不到解决方法......

假设我有一个 data.frame df2,其中有一列列出汽车品牌,另一列列出每个品牌的所有型号,用“,”分隔。我已经获得了 df2 聚合另一个名为 df1 的 data.frame ,主键是模型。

我应该如何继续执行相反的任务(即:从 df2 到 df1)?我的猜测是melt(df2, id=unlist(strsplit('models',',')))......非常感谢!

这是一个MWE:

df1 <- data.frame(model=c('a1','a2','a3','b1','b2','c1','d1','d2','d3','d4'), 
                      brand=c('a','a','a','b','b','c','d','d','d','d'))
df1
collap <- function(x){
  out <- paste(sort(unique(x)), collapse=",")
  return (out)
}
df2 <- aggregate(df1$model, by=list(df1$brand), collap)
names(df2) <- c('brand','models')
df2 #how can I do the opposite task (ie: from df2 to df1)?
4

4 回答 4

2

这里有两种选择:

使用data.tableunlist如下:

library(data.table)
DT <- data.table(df2)
DT[, list(model = unlist(strsplit(as.character(models), ","))), 
   by = brand]
#     brand model
#  1:     a    a1
#  2:     a    a2
#  3:     a    a3
#  4:     b    b1
#  5:     b    b2
#  6:     c    c1
#  7:     d    d1
#  8:     d    d2
#  9:     d    d3
# 10:     d    d4

concat.split.multiple从我的“splitstackshape”包中使用。这种方法的一个好处是能够使用一个简单的命令拆分多个列。

library(splitstackshape)
out <- concat.split.multiple(df2, "models", ",", "long")
out[complete.cases(out), ]
#    brand time models
# 1      a    1     a1
# 2      b    1     b1
# 3      c    1     c1
# 4      d    1     d1
# 5      a    2     a2
# 6      b    2     b2
# 8      d    2     d2
# 9      a    3     a3
# 12     d    3     d3
# 16     d    4     d4
于 2013-11-08T17:33:25.093 回答
1

到处玩,我找到了一种方法来解决这个问题,即使它可能很脏:

df1 <- data.frame(model=as.character(melt(strsplit(df2$models,','))$value), brand=as.character(df2[match(melt(strsplit(df2$models,','))$L1, rownames(df2)),]$brand))

这不是最好的解决方案,因为 data.frames 实际上有更多的列,我不想一个接一个...如果有人知道解决这个问题的更漂亮的方法,我将不胜感激!

于 2013-10-31T16:35:28.757 回答
1

这是我使用plyr包的方法

library("plyr")
ddply(df2, .(brand), function(DF) {
  data.frame(model = strsplit(DF$models, ",")[[1]])
})

作为比较点,这是如何使用相同的包从df1to df2

ddply(df1, .(brand), 
      summarize, models=paste(sort(unique(model)), collapse=","))
于 2013-11-08T18:16:55.553 回答
1

这些天我将tidytext::unnest_tokens用于此任务:

library(tidytext)
df2 %>% 
  unnest_tokens(model, models, token = "regex", pattern = ",")

# A tibble: 10 x 2
    brand model
   <fctr> <chr>
 1      a    a1
 2      a    a2
 3      a    a3
 4      b    b1
 5      b    b2
 6      c    c1
 7      d    d1
 8      d    d2
 9      d    d3
10      d    d4
于 2017-11-01T03:49:24.723 回答