2016-10-12 5 views
0

Iは、次の形式でBillnoと製品列を含むデータセットを有する:スプリットRにおけるデータセット

Billno Prod1 Prod2 Prod3 Prod4 
1  123 176 
2  189 
3  1  2  44  46 
:出力形式のテーブルであるべきである

Billno Product 
1  123 
1  176 
2  189 
3  1 
3  2 
3  44 
3  46 

など

分割機能は機能しますが、データセットには10​​0万を超えるレコードが含まれています。これを行う効率的な方法はありますか?

答えて

2

を行うことができます。

library(dplyr) 
library(tidyr) 

bill <- rep(c(1,1,2,3,3,3,3),5) 
prod <- rep(c(123,176,189, 1,2,44,46),5) 

df <- data.frame(bill=bill, prod=prod) 
#determine max product count (number of columns in result) 
prodmax <- df %>% group_by(bill) %>% summarise(n = n()) 

df %>% group_by(bill) %>% 
    mutate(prodn = paste0("prod",row_number())) %>% 
    spread(prodn, prod) %>% 
#select columns in correct order 
    select_(.dots = c('bill',paste0('prod',seq(1,max(prodmax$n))))) 

結果で:

 bill prod1 prod2 prod3 prod4 
(dbl) (dbl) (dbl) (dbl) (dbl) 
1  1  123 176 NA NA 
2  2  189 NA NA NA 
3  3   1  2 44 46 
+0

ねえ@ Wietze314おかげで多くのことを...これは非常に速く、他のソリューションよりも結果を提供します..しかし、列は出力にはPROD1 prod10 prod11として注文されている...どのように私はやりますprod1 prod2 prod3に順序を変更する......列番号を手動で指定せずに – AB6

+0

解決策を変更しました。列(デフォルトでアルファベット順に並べられている列)が正しい順序であることを確認する方法の1つです。もう1つの解決策は、列がアルファベット順に正しいことを確認することです(つまり、prod01、prod02、...、prod11など) – Wietze314

0

あなたはdplyrと

df <- read.table(header=T, text="Billno Product 
1  123 
1  176 
2  189 
3  1 
3  2 
3  44 
3  46") 
lst <- split(df[,-1], df[,1]) 
lst <- lapply(lst, "length<-", max(lengths(lst))) 
df <- as.data.frame(do.call(rbind, lst)) 
# V1 V2 V3 V4 
# 1 123 176 NA NA 
# 2 189 NA NA NA 
# 3 1 2 44 46 

、その後

names(df) <- sub("V", "prod", names(df)) 
df$billno <- rownames(df) 
0

は、これも行います。

l <- lapply(split(df, df$Billno), function(x) t(x)[2,]) 
df <- as.data.frame(do.call(rbind, lapply(lapply(l, unlist), "[", 
         1:(max(unlist(lapply(l, length))))))) 
names(df) <- paste('Prod', 1:ncol(df), sep='') 
df 
    Prod1 Prod2 Prod3 Prod4 
1 123 176 NA NA 
2 189 NA NA NA 
3  1  2 44 46 
関連する問題