【问题标题】:Loop through data frame and match/populate rows with column values循环遍历数据框并使用列值匹配/填充行
【发布时间】:2021-01-16 16:08:43
【问题描述】:

df1

...other columns...MON TUE WED THU FRI SAT SUN Total
                   8.5 8.5 8.5 8.5 8.5 6.0 0.0 0.0
                   9.0 9.0 9.0 9.0 9.0 6.0 6.0 0.0
                   6.0 7.0 7.0 7.0 7.0 5.0 0.0 0.0
                   ...about 1400 records/rows of data in df1

df2

Day Hours
FRI   0
SAT   0
SUN   0
MON   0
TUE   0
WED   0
THU   0
FRI   0
SAT   0
SUN   0
MON   0
TUE   0
WED   0
...Will keep going until end (28-31 days worth will be listed - all days in a month)

第 1 步

我需要遍历 df2 中的所有行,将“Day”列中的所有记录与 df1 列 MON-SUN 进行匹配...将 df1 中的相应小时数添加到 df2 中的“Hours”列中...仅使用df1 中的第一行,直到所有 df2 都被循环并填充...下面的输出示例

df2 输出

Day   Hours
FRI   8.5
SAT   6.0
SUN   0
MON   8.5
TUE   8.5
WED   8.5
THU   8.5
FRI   8.5
SAT   6.0
SUN   0
MON   8.5
TUE   8.5
WED   8.5
...will continue all the way until last row until all data is filled from 1st row in df1 (repeating itself, just matching the right values)

第二步

在 df2 被循环和填充后 - 然后将 df2 中“小时”列的总和放在 df1“总计”列中

df1 输出

...other columns...MON TUE WED THU FRI SAT SUN Total
                   8.5 8.5 8.5 8.5 8.5 6.0 0.0 88.5
                   9.0 9.0 9.0 9.0 9.0 6.0 6.0
                   6.0 7.0 7.0 7.0 7.0 5.0 0.0

然后重复此过程,直到 df1 中的所有行都已循环并经过相同的过程...因此可能需要使用 match 函数进行某种双循环。我正在努力寻找任何解决方案

使用的代码

row_df1 <- 1
row_df2 <- 1

for (row_df2 in seq(1,nrow(Calendar$Jan))) {
 for (day in week) {
  if (Calendar$Jan[row_df2, 'Day'] == day) {
   Calendar$Jan[row_df2,'Hours'] <- Calctable[row_df1,day]
   row_df2 <- row_df2 + 1
    }
  }
 }

错误信息

 Error in for (day in week) { : invalid for() loop sequence

非常感谢

【问题讨论】:

    标签: r dataframe loops match


    【解决方案1】:
    library(dplyr)
    
    df1 <- data.frame(
      MON = c(1,2,3),
      TUE = c(5,6,7),
      WED = c(8,9,10),
      THU = c(11,12,13),
      FRI = c(14,15,16),
      SAT = c(17,18,19),
      SUN = c(20,21,22))
    
    df2 <- data.frame(
      Day = c('THU', 'FRI', 'SAT', 'SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'),
      Hours = 0
    )
    

    示例df1:(抱歉,我没有花时间为您重新创建确切的数据,请继续执行)

        MON   TUE   WED   THU   FRI   SAT   SUN
      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    1     1     5     8    11    14    17    20
    2     2     6     9    12    15    18    21
    3     3     7    10    13    16    19    22
    

    示例df2

       Day   Hours
       <chr> <dbl>
     1 THU       0
     2 FRI       0
     3 SAT       0
     4 SUN       0
     5 MON       0
     6 TUE       0
     7 WED       0
     8 THU       0
     9 FRI       0
    10 SAT       0
    11 SUN       0
    12 MON       0
    13 TUE       0
    14 WED       0
    15 THU       0
    16 FRI       0
    17 SAT       0
    18 SUN       0
    

    第 1 步:这应该是您正在寻找的算法,按照您描述的方式将 df2 排序为 df1。

    row_df2 <- 1
    
    for (row_df1 in seq(1,nrow(df1))) {
      for (day in c('MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'))
        if (df2[row_df2, 'Day'] == day) {
          df2[row_df2,'Hours'] <- df1[row_df1,day]
          row_df2 <- row_df2 + 1
        }
    }
    

    第 2 步:现在您可以总结 df1 中的值,例如使用dplyr:

    df1 <- df1 %>%
      mutate(
        Sum = MON + TUE + WED + THU + FRI + SAT + SUN
      )
    

    df1:

    # A tibble: 3 x 8
        MON   TUE   WED   THU   FRI   SAT   SUN   Sum
      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    1     1     5     8    11    14    17    20    76
    2     2     6     9    12    15    18    21    83
    3     3     7    10    13    16    19    22    90
    

    df2:

    # A tibble: 18 x 2
       Day   Hours
       <chr> <dbl>
     1 THU      11 <- row 1: THU
     2 FRI      14 <- row 1: FRI
     3 SAT      17 <- ...
     4 SUN      20
     5 MON       2 <- row 2: MON
     6 TUE       6 <- ....
     7 WED       9
     8 THU      12
     9 FRI      15
    10 SAT      18
    11 SUN      21 <- row 2: SUN
    12 MON       3 <- row 3: MON
    13 TUE       7
    14 WED      10
    15 THU      13
    16 FRI      16
    17 SAT      19
    18 SUN      22
    

    两个表中都没有像Date 这样的标识符吗?这将使它更加健壮。然后,您可以按日期进行匹配,而无需依赖正确的开始日期。

    编辑 1:在测试并删除一些错误后更新。

    编辑 2: 突出显示来自 df1 的值将落在 df2 中。我只是使用了与您不同的示例数据(我不想全部输入)。

    编辑 3: 在示例数据中使用 data.frame 而不是 tibble 来证明它应该也可以工作。

    编辑 4:这是你想要的吗?

    row_df1 <- 1
    row_df2 <- 1
    
    for (row_df2 in seq(1,nrow(df2))) {
      for (day in week) {
        if (df2[row_df2, 'Day'] == day) {
          df2[row_df2,'Hours'] <- df1[row_df1,day]
          row_df2 <- row_df2 + 1
        }
    }
    
    df2
    

    将导致:

       Day Hours
    1  THU    11 <- row 1: THU
    2  FRI    14
    3  SAT    17
    4  SUN    20
    5  MON     1
    6  TUE     5
    7  WED     8
    8  THU    11 <- row 1: THU
    9  FRI    14
    10 SAT    17
    11 SUN    20
    12 MON     1
    13 TUE     5
    14 WED     8
    15 THU    11 <- row 1: THU
    16 FRI    14
    17 SAT    17
    18 SUN    20
    

    编辑5:似乎缺少{

    for (row_df2 in seq(1,nrow(Calendar$Jan))) {
     for (day in week) {                                       # <- HERE
      if (Calendar$Jan[row_df2, 'Day'] == day) {
       Calendar$Jan[row_df2,'Hours'] <- Calctable[row_df1,day]
       row_df2 <- row_df2 + 1
        }
      }
    

    编辑 6:

    在编辑 5 中,我分配了 week &lt;- c('MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'),但忘记提及了。它应该看起来像(这里没有特殊的内置变量):

    week <- c('MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN')
    
    for (row_df2 in seq(1,nrow(Calendar$Jan))) {
     for (day in week) {
      if (Calendar$Jan[row_df2, 'Day'] == day) {
       Calendar$Jan[row_df2,'Hours'] <- Calctable[row_df1,day]
       row_df2 <- row_df2 + 1
      }
     }
    }
    

    如果您在代码中的其他位置重复使用week。我用它来测试循环,并在这个答案的先前版本中混合了它。

    【讨论】:

    • 对不起,我不想让你@Daisy 感到困惑。 tibble 基本上是一个 dataframe 。引用package:“tibble() 是创建数据框的好方法。” more。步骤 2 中的代码使用包 dplyr,它是 tidyverse 的一部分,这是一组旨在使数据操作和可视化更容易和更一致的包。我仅以 tibbles 为例,您可以轻松保留 data.frame。
    • 您好,感谢您的解释,非常感谢!我在上面使用了您的代码,但出现以下错误(请参阅问题)...另外我注意到您的 df1 和 df2 的输出与所需的输出非常不同...所以 df2 应该只保存来自 df1 的值Hours' 列...首先使用 df1 中的第一行,然后总计 'Hours' 列并将该总数放在 df1 中的第一行旁边,然后继续进行,直到 df1 中的所有行都经过相同的步骤...结束当所有人都有一个总数时......我希望这是有道理的
    • 只是想在 df1 中添加总数是后一个过程...意味着一旦填充了 df2,则 df2 中的小时数列的总和将放在 df1 中的“总计”列中(行按行)
    • 再次感谢您@randomchars42 - 非常感谢您的帮助
    • @Daisy:至于报错信息:我现在想不通,你是怎么构造你的数据的,是data.frame还是别的什么?
    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 2021-05-21
    • 2017-02-16
    • 1970-01-01
    • 2018-05-30
    • 1970-01-01
    • 2020-05-30
    • 2019-12-16
    相关资源
    最近更新 更多