迭代R数据框中的列名以更改其类型

Sha*_*han 0 r

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)
Run Code Online (Sandbox Code Playgroud)

但!我想在mdy我指定的dX 上迭代地执行上述操作.想象一下,我没有d1-d4而是d1-d142.必须有一种优雅的,即非暴力的方式来做到这一点!

所以,我试过这个.我知道我在做mdy太多专栏,但我只是想让它发挥作用.我已尝试使用seq()等等循环,但我知道我缺少R期望的基于矢量的方法.

f <- function(x) {x <- mdy(x)}
newdf <- apply(df,2,f)
Run Code Online (Sandbox Code Playgroud)

但它会抛出

Warning messages:
1: All formats failed to parse. No formats found. 
...
10: All formats failed to parse. No formats found. 
Run Code Online (Sandbox Code Playgroud)

并且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
Run Code Online (Sandbox Code Playgroud)

我在做什么只是如此st00pid?

所以,一旦完成,我们想做一些日期数学

df$Project1.duration <- (df$Project1.end - df$Project1.start )
df$Project2.duration <- (df$Project2.end - df$Project2.start )
Run Code Online (Sandbox Code Playgroud)

同样在这里.我希望能够迭代所有dX列的所有持续时间,但也许我需要重新整形数据才能实现这一点.如何为所有这些单独编码的不同项目花费大量的持续时间,并将它们重新组合成df,以便我可以为每个项目制作不同持续时间的图.在我的示例中,我有三个不同的持续时间,即行1:3,以便能够比较每个项目的行.

mat*_*fee 5

你的错误是因为你apply是运用mdydf的,而不仅仅是"projectX创建.{起点,终点}".而且因为df[col]是一个data.frame,mdy需要一个矢量 - 尝试df[[col]].

例如

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]])
}
Run Code Online (Sandbox Code Playgroud)

关于计算每个项目的数据(如持续时间),你可以这样做:

projects <- paste0('Project', 1:2) # however many projects
df[paste0(projects, '.duration')] <- df[paste0(projects, '.end')] - df[paste0(projects, '.start')]
Run Code Online (Sandbox Code Playgroud)

但是从长远来看(特别是如果你有很多项目或想要计算每个项目的大量统计数据,而不仅仅是持续时间),你可能会考虑以长格式存储你的数据,即

Project  start  end duration
 1       ...
 1
 1
 2
 2
 2
Run Code Online (Sandbox Code Playgroud)

(可能带有某种ID变量,因此您知道哪个项目2与哪个项目1相关)

然后你可以很容易地做到mydf$duration <- mydf$end - mydf$start,如果你想再次以宽格式,你可以使用reshape.