Reputation: 1037
I have a dataframe like this:
originalDF <- data.frame(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6),
A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0),
A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'),
A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'))
A1 A2 A3 A4 A5
1 1 12.200 T1 1234 0245
2 1 12.200 T2 1234 0245
3 2 15.000 T1 1234 0500
4 3 34.123 T1 1234 0500
5 4 2.000 T2 4321 0600
6 5 66.000 T1 4321 0600
7 6 7.000 T1 4321 0600
8 6 7.000 T1 4321 0800
9 6 7.000 T1 4321 0700
10 6 7.000 T1 4321 0900
11 6 7.000 T1 4321 0900
I want now to reshape it that it finally looks like this:
wantedDF <- cbind.data.frame(originalDF,
A3_0245=c('T1', 'T2', NA, NA, NA, NA, NA, NA, NA, NA, NA),
A3_0500=c(NA, NA, 'T1', 'T1', NA, NA, NA, NA, NA, NA, NA),
A3_0600=c(NA, NA, NA, NA, 'T2', 'T1', 'T1', NA, NA, NA, NA),
A3_0800=c(NA, NA, NA, NA, NA, NA, NA, 'T1', NA, NA, NA),
A3_0700=c(NA, NA, NA, NA, NA, NA, NA, NA, 'T1', NA, NA),
A3_0900=c(NA, NA, NA, NA, NA, NA, NA, NA, NA, 'T1', 'T1'))
A1 A2 A3 A4 A5 A3_0245 A3_0500 A3_0600 A3_0800 A3_0700 A3_0900
1 1 12.200 T1 1234 0245 T1 <NA> <NA> <NA> <NA> <NA>
2 1 12.200 T2 1234 0245 T2 <NA> <NA> <NA> <NA> <NA>
3 2 15.000 T1 1234 0500 <NA> T1 <NA> <NA> <NA> <NA>
4 3 34.123 T1 1234 0500 <NA> T1 <NA> <NA> <NA> <NA>
5 4 2.000 T2 4321 0600 <NA> <NA> T2 <NA> <NA> <NA>
6 5 66.000 T1 4321 0600 <NA> <NA> T1 <NA> <NA> <NA>
7 6 7.000 T1 4321 0600 <NA> <NA> T1 <NA> <NA> <NA>
8 6 7.000 T1 4321 0800 <NA> <NA> <NA> T1 <NA> <NA>
9 6 7.000 T1 4321 0700 <NA> <NA> <NA> <NA> T1 <NA>
10 6 7.000 T1 4321 0900 <NA> <NA> <NA> <NA> <NA> T1
11 6 7.000 T1 4321 0900 <NA> <NA> <NA> <NA> <NA> T1
How can I achieve this? I already asked a kinda similar question here but I can't get to work it :(. This is what I already tried:
DfNames <- unique(originalDF$A5)
wantedDF[,sprintf('A3_%s',DfNames )] <- NA
(now I need conditional add to the each column)
(Base R and data.table solutions preferred!) Thanks in advance!
Upvotes: 2
Views: 309
Reputation: 323376
#You can try this.
library(reshape2)
originalDF <- data.frame(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6),
A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0),
A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'),
A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'),stringsAsFactors = F)
originalDF$Ind=as.numeric(row.names(originalDF))
DF=(acast(originalDF, Ind~paste('A3_',A5), value.var="A3"))
originalDF=cbind(originalDF,DF)
> originalDF
A1 A2 A3 A4 A5 Ind A3_ 0245 A3_ 0500 A3_ 0600 A3_ 0700 A3_ 0800 A3_ 0900
1 1 12.200 T1 1234 0245 1 T1 <NA> <NA> <NA> <NA> <NA>
2 1 12.200 T2 1234 0245 2 T2 <NA> <NA> <NA> <NA> <NA>
3 2 15.000 T1 1234 0500 3 <NA> T1 <NA> <NA> <NA> <NA>
4 3 34.123 T1 1234 0500 4 <NA> T1 <NA> <NA> <NA> <NA>
5 4 2.000 T2 4321 0600 5 <NA> <NA> T2 <NA> <NA> <NA>
6 5 66.000 T1 4321 0600 6 <NA> <NA> T1 <NA> <NA> <NA>
7 6 7.000 T1 4321 0600 7 <NA> <NA> T1 <NA> <NA> <NA>
8 6 7.000 T1 4321 0800 8 <NA> <NA> <NA> <NA> T1 <NA>
9 6 7.000 T1 4321 0700 9 <NA> <NA> <NA> T1 <NA> <NA>
10 6 7.000 T1 4321 0900 10 <NA> <NA> <NA> <NA> <NA> T1
11 6 7.000 T1 4321 0900 11 <NA> <NA> <NA> <NA> <NA> T1
Upvotes: 2
Reputation: 3240
Using data.table
and dcast
.
library(data.table)
dat <- data.table(A1=c(1, 1, 2, 3, 4, 5, 6, 6, 6, 6, 6),
A2=c(12.2, 12.2, 15.0, 34.123, 2.0, 66.0, 7.0, 7.0, 7.0, 7.0, 7.0),
A3=c('T1', 'T2', 'T1', 'T1', 'T2', 'T1', 'T1', 'T1', 'T1', 'T1', 'T1'),
A4=c('1234', '1234', '1234', '1234', '4321', '4321', '4321', '4321', '4321', '4321', '4321'),
A5=c('0245', '0245', '0500', '0500', '0600', '0600', '0600','0800','0700','0900', '0900'))
dat2 <- dcast(dat,
A1 + A2 + A3 + A4 + A5 ~ A5,
value.var = "A3",
fun = function(x) x,
fill = NA)
Results in:
A1 A2 A3 A4 A5 0245 0500 0600 0700 0800 0900
1: 1 12.200 T1 1234 0245 T1 NA NA NA NA NA
2: 1 12.200 T2 1234 0245 T2 NA NA NA NA NA
3: 2 15.000 T1 1234 0500 NA T1 NA NA NA NA
4: 3 34.123 T1 1234 0500 NA T1 NA NA NA NA
5: 4 2.000 T2 4321 0600 NA NA T2 NA NA NA
6: 5 66.000 T1 4321 0600 NA NA T1 NA NA NA
7: 6 7.000 T1 4321 0600 NA NA T1 NA NA NA
8: 6 7.000 T1 4321 0700 NA NA NA T1 NA NA
9: 6 7.000 T1 4321 0800 NA NA NA NA T1 NA
10: 6 7.000 T1 4321 0900 NA NA NA NA NA T1
You'll notice that row 11 is missing. This is because 10 and 11 were dups. You can always use merge to pull these back in.
merge(dat,
dat2,
by = c("A1", "A2", "A3", "A4", "A5"),
all.x = TRUE)
A1 A2 A3 A4 A5 0245 0500 0600 0700 0800 0900
1: 1 12.200 T1 1234 0245 T1 NA NA NA NA NA
2: 1 12.200 T2 1234 0245 T2 NA NA NA NA NA
3: 2 15.000 T1 1234 0500 NA T1 NA NA NA NA
4: 3 34.123 T1 1234 0500 NA T1 NA NA NA NA
5: 4 2.000 T2 4321 0600 NA NA T2 NA NA NA
6: 5 66.000 T1 4321 0600 NA NA T1 NA NA NA
7: 6 7.000 T1 4321 0600 NA NA T1 NA NA NA
8: 6 7.000 T1 4321 0700 NA NA NA T1 NA NA
9: 6 7.000 T1 4321 0800 NA NA NA NA T1 NA
10: 6 7.000 T1 4321 0900 NA NA NA NA NA T1
11: 6 7.000 T1 4321 0900 NA NA NA NA NA T1
You can also easily set the column names:
setnames(dat2, unique(dat$A5), paste("A3", unique(dat$A5), sep = "_"))
A1 A2 A3 A4 A5 A3_0245 A3_0500 A3_0600 A3_0700 A3_0800 A3_0900
1: 1 12.200 T1 1234 0245 T1 NA NA NA NA NA
2: 1 12.200 T2 1234 0245 T2 NA NA NA NA NA
3: 2 15.000 T1 1234 0500 NA T1 NA NA NA NA
4: 3 34.123 T1 1234 0500 NA T1 NA NA NA NA
5: 4 2.000 T2 4321 0600 NA NA T2 NA NA NA
6: 5 66.000 T1 4321 0600 NA NA T1 NA NA NA
7: 6 7.000 T1 4321 0600 NA NA T1 NA NA NA
8: 6 7.000 T1 4321 0700 NA NA NA T1 NA NA
9: 6 7.000 T1 4321 0800 NA NA NA NA T1 NA
10: 6 7.000 T1 4321 0900 NA NA NA NA NA T1
11: 6 7.000 T1 4321 0900 NA NA NA NA NA T1
Upvotes: 1
Reputation: 17299
A data.table
solution:
library(data.table)
dt <- as.data.table(originalDF)
dt[, toc := paste('A3', A5, sep = '_')]
res <- dcast(dt, A1 + A2 + A3 + A4 + A5 + rowid(A1) ~ toc, value.var = 'A3')[, A1_1 := NULL]
# > res[]
# A1 A2 A3 A4 A5 A3_0245 A3_0500 A3_0600 A3_0700 A3_0800 A3_0900
# 1: 1 12.200 T1 1234 0245 T1 NA NA NA NA NA
# 2: 1 12.200 T2 1234 0245 T2 NA NA NA NA NA
# 3: 2 15.000 T1 1234 0500 NA T1 NA NA NA NA
# 4: 3 34.123 T1 1234 0500 NA T1 NA NA NA NA
# 5: 4 2.000 T2 4321 0600 NA NA T2 NA NA NA
# 6: 5 66.000 T1 4321 0600 NA NA T1 NA NA NA
# 7: 6 7.000 T1 4321 0600 NA NA T1 NA NA NA
# 8: 6 7.000 T1 4321 0700 NA NA NA T1 NA NA
# 9: 6 7.000 T1 4321 0800 NA NA NA NA T1 NA
# 10: 6 7.000 T1 4321 0900 NA NA NA NA NA T1
# 11: 6 7.000 T1 4321 0900 NA NA NA NA NA T1
Upvotes: 2