4

次の構造のデータ フレームがあるとします。

df <- data.frame(a=c(1,2,3,4), b=c("job1;job2", "job1a", "job4;job5;job6", "job9;job10;job11"))

ここで、列bはセミコロンで区切られたリストです (行ごとにバランスが取れていません)。理想的な data.frame は次のようになります。

id,job,jobNum
1,job1,1
1,job2,2
...
3,job6,3
4,job9,1
4,job10,2
4,job11,3

ほぼ 2 時間 (170K 行) かかる部分的なソリューションがあります。

# Split the column by the semicolon.  Results in a list.
df$allJobs <- strsplit(df$b, ";", fixed=TRUE)

# Function to reshape column that is a list as a data.frame
simpleStack <- function(data){
    start <- as.data.frame.list(data)                       
    names(start) <-c("id", "job")
    return(start)
}
# pylr!
system.time(df2 <- ddply(df, .(id), simpleStack))

サイズの問題のようです。

system.time(df2 <- ddply(df[1:4000,c("id", "allJobs")], .(id), simpleStack))

9秒しかかかりません。最初に sapply (別の関数を使用) を使用して一連の data.frames に変換するのは高速ですが、必要な「rbind」にはさらに時間がかかります。

4

2 に答える 2

12
#Split by ; as before
allJobs <- strsplit(df$b, ";", fixed=TRUE)

#Replicate a by the number of jobs in each case
n <- sapply(allJobs, length)
id <- rep(df$a, times = n)

#Turn allJobs into a vector
job <- unlist(allJobs)

#Retrieve position of each job
jobNum <- unlist(lapply(n, seq_len))

#Combine into a data frame
df2 <- data.frame(id = id, job = job, jobNum = jobNum)
于 2011-01-18T14:09:22.290 に答える