So I have the data.frame
dat = data.frame(x = c('Sir Lancelot the Brave', 'King Arthur',
'The Black Knight', 'The Rabbit'), stringsAsFactors=F)
> dat
x
1 Sir Lancelot the Brave
2 King Arthur
3 The Black Knight
4 The Rabbit
And I want to transform it into the data frame
> dat2
x 1 2 3 4
1 Sir Lancelot the Brave Sir Lancelot the Brave
2 King Arthur King Arthur
3 The Black Knight The Black Knight
4 The Rabbit The Rabbit
strsplit returns the data as a list
sbt <- strsplit(dat$x, " ")
> sbt
[[1]]
[1] "Sir" "Lancelot" "the" "Brave"
[[2]]
[1] "King" "Arthur"
[[3]]
[1] "The" "Black" "Knight"
[[4]]
[1] "The" "Rabbit"
and as.data.table does not create NULL values where it should, but repeats values
> t(as.data.table(sbt))
[,1] [,2] [,3] [,4]
V1 "Sir" "Lancelot" "the" "Brave"
V2 "King" "Arthur" "King" "Arthur"
V3 "The" "Black" "Knight" "The"
V4 "The" "Rabbit" "The" "Rabbit"
I guess I really would like an argument to as.data.table(x, repeat=FALSE), else how can I accomplish this job?
Here's one option. The single complication is that you need to first convert each vector to a data.frame with one row, as data.frames are what rbind.fill()
expects.
library(plyr)
rbind.fill(lapply(sbt, function(X) data.frame(t(X))))
# X1 X2 X3 X4
# 1 Sir Lancelot the Brave
# 2 King Arthur <NA> <NA>
# 3 The Black Knight <NA>
# 4 The Rabbit <NA> <NA>
My own inclination, though, would be to just use base R, like this:
n <- max(sapply(sbt, length))
l <- lapply(sbt, function(X) c(X, rep(NA, n - length(X))))
data.frame(t(do.call(cbind, l)))
# X1 X2 X3 X4
# 1 Sir Lancelot the Brave
# 2 King Arthur <NA> <NA>
# 3 The Black Knight <NA>
# 4 The Rabbit <NA> <NA>
sbt = strsplit(dat$x, " ")
sbt
#[[1]]
#[1] "Sir" "Lancelot" "the" "Brave"
#[[2]]
#[1] "King" "Arthur"
#[[3]]
#[1] "The" "Black" "Knight"
#[[4]]
#[1] "The" "Rabbit"
ncol = max(sapply(sbt,length))
ncol
# [1] 4
as.data.table(lapply(1:ncol,function(i)sapply(sbt,"[",i)))
# V1 V2 V3 V4
# 1: Sir Lancelot the Brave
# 2: King Arthur NA NA
# 3: The Black Knight NA
# 4: The Rabbit NA NA
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With