【问题标题】:R: Avoid repeating lines of code using R subsets in scriptsR:避免在脚本中使用 R 子集重复代码行
【发布时间】:2015-02-13 11:53:10
【问题描述】:

我对 R 非常陌生,但多年来一直在开发 SAS 程序(和 VBA)。好吧,问题是我有 4 行 R 代码(脚本?),我想重复 44 次。对 22 个不同的火车站中的每一个进行两次,指示火车是进站还是出站。四行代码分别是:

dataGL_FLIin <- subset( dataGL_all, select = c(Tidsinterval, Dag, M.ned, Ugenr.,Kode, Ugedag, FLIin))
names(dataGL_FLIin)[names(dataGL_FLIin)=='FLIin'] <- 'GL_Antal'
dataGL_FLIin$DIR<-"IN"
dataGL_FLIin$STATION<-"FLI    

为了避免将 4 行重复 44 次,我需要 2 个“宏变量”(是的,我知道,这只是 SAS 的东西,抱歉)。一个“宏变量”表示火车站,一个表示方向。在上面的示例中,火车站是 FLI,方向是 in。下面同样的 4 条线路展示了火车站 FBE,这次是在out-前进方向。

dataGL_FBEout <- subset( dataGL_all, select = c(Tidsinterval, Dag, M.ned, Ugenr.,Kode, Ugedag, FBEout))
names(dataGL_FBEout)[names(dataGL_FBEout)=='FBEout'] <- 'GL_Antal'
dataGL_FBEout$DIR<-"OUT"
dataGL_FBEout$STATION<-"FBE"

我看了很多地方,尝试了很多 R-functions 和 R-lists 的组合,但我无法让它工作。很可能我弄错了。如果这个问题(太)愚蠢,我会提前道歉,但是非常感谢您对此事的任何帮助。

请。请注意,我最终想要创建 44 个不同的数据框: 1) 数据GL_FLIin 2) 数据GL_FBEout 3) 等等……

添加:我的问题的2站2方向示例

'The one data frame I have'
Date<-c("01-01-15 04:00","01-01-15 04:20","01-01-15 04:40")
FLIin<-c(96,39,72)
FLIout<-c(173,147,103)
FBEin<-c(96,116,166)
FBEout<-c(32,53,120)
dataGL_all<-data.frame(Date, FLIin, FLIout, FBEin, FBEout)

'The four data frames I would like'
GL_antal<-c(96,39,72)
Station<-("FLI")
Dir<-("IN")
dataGL_FLIin<-data.frame(Date, Station, Dir, GL_antal)

GL_antal<-c(173,147,103)
Station<-("FLI")
Dir<-("OUT")
dataGL_FLIout<-data.frame(Date, Station, Dir, GL_antal)

GL_antal<-c(96,116,166)
Station<-("FBE")
Dir<-("IN")
dataGL_FBEin<-data.frame(Date, Station, Dir, GL_antal)

GL_antal<-c(32,53,120)
Station<-("FBE")
Dir<-("OUT")
dataGL_FBEout<-data.frame(Date, Station, Dir, GL_antal)

谢谢, 拉尔斯

【问题讨论】:

  • 你不能只使用一个函数并传递火车站和方向的变量吗?
  • 嗨,克里斯蒂安,谢谢您的回复。是的,您的建议可能是解决方案,但我无法找出正确的语法...
  • 你能添加一个可重现的例子吗?至少是原始数据以及最终结果应该是什么样子?
  • 谢谢你,克里斯蒂安!

标签: r loops macros subset


【解决方案1】:

通过您的示例,您现在更清楚您想要什么,我再试一次。我使用您的问题和定义中定义的dataGL_all

stations <- rep(c("FLI","FBE"),each=2)
directions <- rep(c("in","out"),times=length(stations)/2)

您还可以从数据框中提取站点和方向。使用您的示例,以下将起作用

stations <- substr(names(dataGL_all)[-1],1,3)
directions <- substr(names(dataGL_all)[-1],4,6)

然后,我定义将处理数据的函数:

dataGLfun <- function(station,direction) {
    name <- paste0(station,direction)
    dataGL <- dataGL_all[,c("Date", name)]
    names(dataGL)[names(dataGL)==name] <- 'GL_Antal'
    dataGL$DIR<-direction
    dataGL$STATION<-station
    dataGL
}

现在我将这个函数应用到所有有两个方向的车站:

dataGL <- mapply(dataGLfun,stations,directions,SIMPLIFY=FALSE)
names(dataGL) <- paste0(stations,directions)

现在,您可以获取每个站点和方向组合的数据框。例如,您的问题中的两个示例是dataGL$FLIindataGL$FBEout。有一个$ 而不是_ 的原因是我实际上并没有为每个数据框创建一个单独的变量。相反,我创建了一个列表,其中列表的每个元素都是数据框之一。这样做的好处是以后对所有数据帧做一些事情会更容易。使用您的解决方案,您必须键入所有各种变量名称,但如果数据框在列表中,您可以使用 lapply 之类的函数来处理它们。

如果您希望有许多不同的变量,您可以执行以下操作

for (i in seq_along(stations)) {
    assign(paste0("dataGL_",stations[i],directions[i]), dataGLfun(stations[i],directions[i]))
}

但是,在我看来,这不是你应该在 R 中解决这个问题的方式。

【讨论】:

  • 您的代码看起来很棒,谢谢,但是它并没有产生我希望的结果。请查看我在上面的问题中添加的 2 站 2 方向示例,再次感谢 Stibu
  • 感谢您提供示例数据。我希望我现在正确理解了你的意图。我相应地调整了答案。
  • 感谢 Stibu,这太棒了。你确实解决了我的问题,并将我的主程序从数百行减少到几行。再次感谢。我现在看看我是否可以将 4 个列表成员 dataGL$FLIin、dataGL$FLIout、dataGL$FBEin 和 dataGL$FBEout“连接”(rbind)到一个列表或数据框,然后将其导出到 csv.-file (write.csv),所以我可以在 Excel 中使用它来制作数据透视表。我会试一试,但如果我失败了可能会再次寻求帮助:)
  • 可以按如下方式组合数据框:dataGL_combined&lt;-do.call(rbind,dataGL).
  • 感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2015-04-05
  • 2015-05-02
  • 1970-01-01
  • 2021-03-03
  • 2014-03-07
  • 2015-04-20
相关资源
最近更新 更多