Reputation: 195
I have a dataframe which has a column for a date, another column for an amount, and various columns that contain years. I want to put the values from the amount column into the year column that corresponds to year in the date column. For example,
ID Date Amount 2010 2011 2012
01 2010/05/05 200 200
02 2011/05/05 300 300
03 2012/05/05 400 400
Is there a way I can dynamically choose which column to mutate based on the value of the date column?
Upvotes: 0
Views: 440
Reputation: 42592
For the sake of completeness, there is also a "one-liner" using data.table
:
library(data.table)
dcast(DF, ID + Date + Amount ~ year(Date), fill = "")
Note that the year
columns are computed on-the-fly. So there is no need to create a helper y
variable before reshaping.
ID Date Amount 2010 2011 2012 1 01 2010-05-05 200 200 2 02 2011-05-05 300 300 3 03 2012-05-05 400 400
DF <- structure(list(ID = c("01", "02", "03"), Date = structure(c(14734,
15099, 15465), class = "Date"), Amount = c(200L, 300L, 400L)), .Names = c("ID",
"Date", "Amount"), row.names = c(NA, -3L), class = "data.frame")
Upvotes: 1
Reputation: 5068
After transforming the date to a year using lubridate
's year
, you can use spread
from the tidyr
package to spread your data out:
library(dplyr)
library(tidyr)
df = read.table(text = "ID Date Amount
01 2010/05/05 200
02 2011/05/05 300
03 2012/05/05 400 ", header= TRUE)
df %>%
mutate(y = lubridate::year(Date)) %>%
spread(key = y, value = Amount)
The missing data points will be NA
's. If you prefer blank strings like in your sample, instead try:
... %>%
spread(key = y, value = Amount, fill = "")
Note that the resulting dataframe no longer has an Amount
column, but you can get it back by merging to the original data.
Upvotes: 4