2013-10-31 26 views
1

我有一個小問題,這似乎是在概念很容易,但我不能找到這樣做的方式......熔體+ strsplit,或相反聚集

說我有一個data.frame DF2與一欄列出汽車品牌,另一欄列出每個品牌的所有車型,用','分隔。我已經獲得df2聚合另一個名爲df1的數據框架,主鍵是模型。

我該如何着手做相反的工作(即:從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)? 
+0

您應該使用R標籤更好地查看您的R相關問題。 – A5C1D2H2I1M1N2O1R2T1

回答

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 
+0

注意!謝謝!! – DaniCee

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實際上有更多的列,我不想一個接一個地去......如果有人知道更好的方法來解決這個問題,我將不勝感激!

1

這裏有兩個選擇:

使用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 
1

這是我將如何使用plyr

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

作爲比較的角度去做,這是如何使用同一個包從去df1df2

ddply(df1, .(brand), 
     summarize, models=paste(sort(unique(model)), collapse=","))