【问题标题】:Nested For Loop in R to iterate between columns在 R 中嵌套 For 循环以在列之间进行迭代
【发布时间】:2020-09-02 17:20:27
【问题描述】:

我正在尝试生成一个数据集,在该数据集中,我在以后每三行更改第一列,当我更改第一列时,第二列和第三列也会随之更改。下面给出的例子。我对如何使用嵌套的 for 循环实现这一点有点困惑。

df = NULL 
   for (CDRID in 1:3) 
{ 
for (STARTDATE in 20200517:20200519) 
{ 
for (PRIIDENTITY in 4:6) 
{
    df1 = rbind(df, data.frame  ( "CDR_ID"=CDRID, "START_DATE"=STARTDATE, "PRI_IDENTITY"=PRIIDENTITY)) }}}

【问题讨论】:

  • 请不要发布代码/数据/错误的图像:它不能被复制或搜索 (SEO),它会破坏屏幕阅读器,并且它可能不适合某些移动设备。参考:meta.stackoverflow.com/a/285557(和xkcd.com/2116)。请直接包含代码、控制台输出或数据(例如,dput(head(x))data.frame(...))。
  • 迭代增长的 data.frames 在概念上有效,但速度非常慢:每次调用 rbind,它都会对所有行进行完整的复制。这意味着如果您循环这九次(如您的循环所示),第一批在内存中重复八次(想象一下它是如何扩展的)。最好将它们添加到list,然后在最后将它们与do.call(rbind, L)dplyr::bind_rows(L)data.table::rbindlist(L) 之一结合起来。 (请参阅R Inferno 中的第 2 章“不断增长的对象”。)

标签: r for-loop nested-loops


【解决方案1】:
df <- data.frame(ID=1:3, START_DATE=20200517:20200519, PRI_IDENTITY=4:6)
df[rep(seq_len(nrow(df)), each=3),]
#     ID START_DATE PRI_IDENTITY
# 1    1   20200517            4
# 1.1  1   20200517            4
# 1.2  1   20200517            4
# 2    2   20200518            5
# 2.1  2   20200518            5
# 2.2  2   20200518            5
# 3    3   20200519            6
# 3.1  3   20200519            6
# 3.2  3   20200519            6

一个想法:20200517:20200519,我假设这些是日期。这是脆弱的,因为它不知道几个月之间的包装天数。在 R 中,使用正确的 Date 对象可能会更好。有了这个,试试:

> df <- data.frame(ID=1:3, START_DATE=seq.Date(as.Date("2020-05-17"), as.Date("2020-05-19"), by="days"), PRI_IDENTITY=4:6)
Browse[2]> df[rep(seq_len(nrow(df)), each=3),]
    ID START_DATE PRI_IDENTITY
1    1 2020-05-17            4
1.1  1 2020-05-17            4
1.2  1 2020-05-17            4
2    2 2020-05-18            5
2.1  2 2020-05-18            5
2.2  2 2020-05-18            5
3    3 2020-05-19            6
3.1  3 2020-05-19            6
3.2  3 2020-05-19            6

正如 akrun 建议的那样,如果您正在使用(或可以使用)来自 tidyverse 的软件包,那么您可以代替 rep(seq_len(... 部分,

# df <- data.frame(...)
tidyr::uncount(df, 3)

【讨论】:

  • 另一个选项是df %&gt;% uncount(3)
  • 非常感谢您的帮助也感谢您指出日期应该按照指定的日期时间格式递增。使用 seq_len 解决了这个问题。
  • 如果这回答了您的问题,请accept it。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-15
  • 1970-01-01
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多