【问题标题】:R: How to use Apply function taking multiple inputs across rows and columnsR:如何使用 Apply 函数在行和列中获取多个输入
【发布时间】:2017-07-19 17:05:36
【问题描述】:
Jan   Feb   Mar   Apr   May   Jun   Jul   Aug  Sep   Oct   Nov   Dec  

 13    0     14     0    16     0    22     0    20     0    18     0
 30    0     30     0     0     0     0     0     0     0    30     0
 0     0     29    33     0    48     0    49     0    50     0    33
 0     45    30     0     0    55     0    69    55     0     0    40
 0     54    0     45     0    48     0    73     0    46     0    36
 16    0     15     0    13     0    16     0    24     0    23     0
 0     32    26     0     0    57     0    65    49     0     0    32
 6     0     6      0     5     0     7     0     6     0     6     0
 0     665   310   271    0   646     0   706     0   585     0   516
 0     70    41     0     0   101     0   112   112     0     0    90

我目前有这个稀疏数据框,我想用右边的一半值替换所有 0,并用 1 月值的一半替换 12 月的零。

例如,第一行应该如下所示:

Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep   Oct   Nov   Dec

6.5    7    7     8     8     11     11    10    10     9     9    6.5

因此,基本上一年的总数应该保持不变,并且应该更均匀地分布在各个月份。

我尝试使用循环,但我的实际数据跨越多年,数十万行,循环太慢了。我知道 apply 是要走的路,但无法弄清楚我的函数应该是什么或如何将其应用于行和列。

谢谢

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    我制作了dfout 以保持原始df 不变。 dfv2 为我们提供了应该放入 dfoutdfv3 中的值,这有助于找到应该划分哪些列(那些已被替换的列)。条件df==0 是此解决方案中的关键元素。我希望有人为此发布 解决方案。

    dfout <- df
    dfv2 <- data.frame(df[,-1], Jan = df[,1])   
    dfv3 <- data.frame(Dec = df[,12], df[,-12]) 
    dfout[df==0] <- dfv2[df==0]
    dfout[df==0 | dfv3==0] <- dfout[df==0 | dfv3==0] / 2
    
    rowSums(df) - rowSums(dfout)
    
    #  [1] 0 0 0 0 0 0 0 0 0 0
    
    
    dfout
    
    #      Jan   Feb   Mar   Apr   May   Jun   Jul   Aug   Sep   Oct   Nov   Dec 
    # 1    6.5   7.0   7.0   8.0   8.0  11.0  11.0  10.0  10.0   9.0   9.0   6.5 
    # 2   15.0  15.0  15.0   0.0   0.0   0.0   0.0   0.0   0.0  15.0  15.0  15.0 
    # 3    0.0  14.5  14.5  33.0  24.0  24.0  24.5  24.5  25.0  25.0  16.5  16.5 
    # 4   22.5  22.5  30.0   0.0  27.5  27.5  34.5  34.5  55.0   0.0  20.0  20.0 
    # 5   27.0  27.0  22.5  22.5  24.0  24.0  36.5  36.5  23.0  23.0  18.0  18.0 
    # 6    8.0   7.5   7.5   6.5   6.5   8.0   8.0  12.0  12.0  11.5  11.5   8.0 
    # 7   16.0  16.0  26.0   0.0  28.5  28.5  32.5  32.5  49.0   0.0  16.0  16.0 
    # 8    3.0   3.0   3.0   2.5   2.5   3.5   3.5   3.0   3.0   3.0   3.0   3.0 
    # 9  332.5 332.5 310.0 271.0 323.0 323.0 353.0 353.0 292.5 292.5 258.0 258.0 
    # 10  35.0  35.0  41.0   0.0  50.5  50.5  56.0  56.0 112.0   0.0  45.0  45.0
    

    数据:

    df <- structure(list(Jan = c(13L, 30L, 0L, 0L, 0L, 16L, 0L, 6L, 0L, 
    0L), Feb = c(0L, 0L, 0L, 45L, 54L, 0L, 32L, 0L, 665L, 70L), Mar = c(14L, 
    30L, 29L, 30L, 0L, 15L, 26L, 6L, 310L, 41L), Apr = c(0L, 0L, 
    33L, 0L, 45L, 0L, 0L, 0L, 271L, 0L), May = c(16L, 0L, 0L, 0L, 
    0L, 13L, 0L, 5L, 0L, 0L), Jun = c(0L, 0L, 48L, 55L, 48L, 0L, 
    57L, 0L, 646L, 101L), Jul = c(22L, 0L, 0L, 0L, 0L, 16L, 0L, 7L, 
    0L, 0L), Aug = c(0L, 0L, 49L, 69L, 73L, 0L, 65L, 0L, 706L, 112L
    ), Sep = c(20L, 0L, 0L, 55L, 0L, 24L, 49L, 6L, 0L, 112L), Oct = c(0L, 
    0L, 50L, 0L, 46L, 0L, 0L, 0L, 585L, 0L), Nov = c(18L, 30L, 0L, 
    0L, 0L, 23L, 0L, 6L, 0L, 0L), Dec = c(0L, 0L, 33L, 40L, 36L, 
    0L, 32L, 0L, 516L, 90L)), .Names = c("Jan", "Feb", "Mar", "Apr", 
    "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"), class = 
    "data.frame", row.names = c(NA, -10L))
    

    更新:

    如果你想让所有元素都非零,你可以使用while:

    original.df <- df
    
    while(any(df==0)) {
                       dfout <- df
                       dfv2 <- data.frame(df[,-1], Jan = df[,1])   
                       dfv3 <- data.frame(Dec = df[,12], df[,-12]) 
                       dfout[df==0] <- dfv2[df==0]
                       dfout[df==0 | dfv3==0] <- dfout[df==0 | dfv3==0] / 2
                       df <- dfout
                      }
    
    rowSums(original.df) - rowSums(dfout)
    
    #  [1] 0 0 0 0 0 0 0 0 0 0
    
    dfout
    
    #      Jan   Feb   Mar    Apr    May    Jun    Jul   Aug   Sep   Oct Nov   Dec 
    # 1    6.5   7.0   7.0   8.00   8.00  11.00  11.00  10.0  10.0   9.0   9   6.5 
    # 2   15.0  15.0  15.0   0.23   0.23   0.47   0.94   1.9   3.8   7.5  15  15.0 
    # 3    7.2   7.2  14.5  33.00  24.00  24.00  24.50  24.5  25.0  25.0  16  16.5 
    # 4   22.5  22.5  30.0  13.75  13.75  27.50  34.50  34.5  55.0  10.0  10  20.0 
    # 5   27.0  27.0  22.5  22.50  24.00  24.00  36.50  36.5  23.0  23.0  18  18.0 
    # 6    8.0   7.5   7.5   6.50   6.50   8.00   8.00  12.0  12.0  11.5  12   8.0 
    # 7   16.0  16.0  26.0  14.25  14.25  28.50  32.50  32.5  49.0   8.0   8  16.0 
    # 8    3.0   3.0   3.0   2.50   2.50   3.50   3.50   3.0   3.0   3.0   3   3.0 
    # 9  332.5 332.5 310.0 271.00 323.00 323.00 353.00 353.0 292.5 292.5 258 258.0 
    # 10  35.0  35.0  41.0  25.25  25.25  50.50  56.00  56.0 112.0  22.5  22  45.0
    

    【讨论】:

      猜你喜欢
      • 2021-07-02
      • 2020-01-21
      • 2017-09-24
      • 1970-01-01
      • 1970-01-01
      • 2013-08-13
      • 2021-09-03
      • 2016-02-23
      • 1970-01-01
      相关资源
      最近更新 更多