library(lubridate)
# data to build the df
d1 <- c("1/2/14", "3/5/15", "1/13/11") #start
d2 <- c("1/2/15", "4/5/15", "6/18/15") #stop
d3 <- c("5/16/08", "1/7/07", "6/22/01") #start
d4 <- c("11/29/12", "8/5/14", "1/13/12") #stop
a <- c("Blah", "Blah", "Blah")
b <- c("Blah", "Blah", "Blah")
c <- c("Blah", "Blah", "Blah")
f <- c("Blah", "Blah", "Blah")
colNames <- c("Col.a", "Col.b", "Col.c", "Project1.start", "Project1.end", "Project2.start", "Project2.end", "Col.f")
# assemble the df
df <- data.frame(a,b,c,d1,d2,d3,d4,f)
names(df) <- colNames
# change the char cols for dX into POSIX date objects to play nicely with
# lubridate
df$Project1.start <- mdy(df$Project1.start)
df$Project1.end <- mdy(df$Project1.end)
df$Project2.start <- mdy(df$Project2.start)
df$Project2.end <- mdy(df$Project2.end)
BUT!我想在我指定的dX上迭代地执行上面的mdy
。
想象一下,我没有d1-d4而是d1-d142。一定要优雅,
即,非暴力的方式这样做!
所以,我试过这个。我知道我在太多列上做mdy
,但我只是想让它完全正常工作。我已尝试使用seq()
等循环,但我知道
我错过了R所期望的基于矢量的方法。
f <- function(x) {x <- mdy(x)}
newdf <- apply(df,2,f)
但它会抛出
Warning messages:
1: All formats failed to parse. No formats found.
...
10: All formats failed to parse. No formats found.
并且newdf很糟糕:
Col.a Col.b Col.c Project1.start Project1.end Project2.start Project2.end Col.f
[1,] NA NA NA NA NA NA NA NA
[2,] NA NA NA NA NA NA NA NA
[3,] NA NA NA NA NA NA NA NA
Project1.duration Project2.duration
[1,] NA NA
[2,] NA NA
[3,] NA NA
我在做什么就是这么st00pid?
所以,一旦完成,我们想做一些日期数学
df$Project1.duration <- (df$Project1.end - df$Project1.start )
df$Project2.duration <- (df$Project2.end - df$Project2.start )
在这里。我希望能够迭代所有dX列的所有持续时间,但也许我需要重新整形数据才能实现这一点。如何为所有这些单独编码的不同项目花费大量的持续时间,并将它们重新组合成df,以便我可以为每个项目制作不同持续时间的图。在我的示例中,我有三个不同的持续时间,即行1:3,以便能够比较每个项目的行。
答案 0 :(得分:5)
您的错误是因为apply
正在将mdy
应用于df
的每个列的,而不仅仅是&#34; ProjectX。{start,end }&#34;那些。而且因为df[col]
是data.frame
,mdy
需要矢量 - 请尝试df[[col]]
。
e.g。
cols <- grep('Project', names(df))
# do a one-liner like this
df[cols] <- lapply(df[cols], mdy)
# or a loop like this if you want
for (col in cols) {
df[[col]] <- mdy(df[[col]])
}
关于计算每个项目数据(如持续时间),你可以这样做:
projects <- paste0('Project', 1:2) # however many projects
df[paste0(projects, '.duration')] <- df[paste0(projects, '.end')] - df[paste0(projects, '.start')]
但是从长远来看(特别是如果你有很多项目或想要计算每个项目的大量统计数据,而不仅仅是持续时间),你可以考虑以长格式存储数据,即
Project start end duration
1 ...
1
1
2
2
2
(可能带有某种ID变量,因此您知道哪个项目2与哪个项目1相关)
然后您可以轻松地执行mydf$duration <- mydf$end - mydf$start
,如果您想再次使用宽格式,则可以使用reshape
。