计算 R 中两两连续数字的平均值

Aza*_*aei 3 loops r dplyr

我有一个数据集,其中每年都有一些基于特定年份的列中的数据。

    result_birth <- tibble::tibble( "1970" =c(8.816455, 21.41139,39.0443,51.639236, 59.196197,      100.759485, 76.829107,103.278472,79.348094,99.499991, 81.867081, 78.088601), 
                      "1971"=  c(18.878066 ,30.204906 ,42.790284 ,65.443964 ,69.219577 ,80.546417   ,114.526936 ,94.390332 ,108.234248 ,83.063492 ,103.200096 ,72.99519 ), 
                      "1972"=  c(8.801375 ,22.632107 ,36.462839 ,56.580268 ,69.153661 ,76.697696 ,80.469714 ,109.388518 ,96.815125 ,108.131179 ,69.153661 ,91.785768 ), 
                      "1973"= c(14.675905 ,20.790865 ,31.797794 ,64.818581 ,58.70362 ,86.832438 ,85.609446 ,96.616375 ,97.839367 ,78.271493 ,105.177319 ,53.811652 ))
   
     
     
Run Code Online (Sandbox Code Playgroud)

我想要从数据框的底部获取两两数据的平均值。最后的 rwos 必须与原始数据集相同。例如,对于第一行,我们将有这样的内容:

旧数据和新数据

我写了一些代码来做到这一点,但是这段代码有两个问题:首先,它从上面开始;因此,第一行必须与旧数据相同,(我想要相反,最后一行与旧数据相同)。其次,这些代码非常繁琐,我需要一些更加用户友好的东西。

nrows <- nrow(result_birth)

total_birth <- data.frame(matrix(NA, nrow = nrows, ncol = 
ncol(result_birth)))

for (i in 1:ncol(result_birth)) {
    for (j in 2:nrows) {
        total_birth[j, i]<-(result_birth[j,i]+result_birth[j-1,i])/2
    }
}
Run Code Online (Sandbox Code Playgroud)

jps*_*ith 5

您可以使用中的dplyr::lead()和参数来完成此操作。通常,您的函数可能只是在最后一行中留下一个- 因为您希望最后一行等于该行中的原始值,所以一个快速的解决方法是在其中嵌套一个语句来测试是否存在:.namesdplyr::mutate~(.x + lead(.x)) / 2)NAif_elseNA

library(dplyr)

result_birth %>% 
  mutate(across(everything(), 
                ~(.x + if_else(!is.na(lead(.x)), lead(.x), .x)) / 2, 
                .names = "mean_{col}"))
Run Code Online (Sandbox Code Playgroud)

输出:

#    `1970` `1971` `1972` `1973` mean_1970 mean_1971 mean_1972 mean_1973
# <dbl>  <dbl>  <dbl>  <dbl>     <dbl>     <dbl>     <dbl>     <dbl>
# 1   8.82   18.9   8.80    14.7      15.1      24.5      15.7      17.7
# 2   21.4    30.2  22.6    20.8      30.2      36.5      29.5      26.3
# 3   39.0    42.8  36.5    31.8      45.3      54.1      46.5      48.3
# 4   51.6    65.4  56.6    64.8      55.4      67.3      62.9      61.8
# 5   59.2    69.2  69.2    58.7      80.0      74.9      72.9      72.8
# 6   101.    80.5  76.7    86.8      88.8      97.5      78.6      86.2
# 7   76.8    115.  80.5    85.6      90.1      104.      94.9      91.1
# 8   103.    94.4  109.    96.6      91.3      101.      103.      97.2
# 9   79.3    108.  96.8    97.8      89.4      95.6      102.      88.1
# 10  99.5    83.1  108.    78.3      90.7      93.1      88.6      91.7
# 11  81.9    103.  69.2    105.      80.0      88.1      80.5      79.5
# 12  78.1    73.0  91.8    53.8      78.1      73.0      91.8      53.8
Run Code Online (Sandbox Code Playgroud)

如果您只想用平均值替换原始列(而不是创建新列),只需删除参数.names

result_birth %>% 
  mutate(across(everything(), 
                ~(.x + if_else(!is.na(lead(.x)), lead(.x), .x)) / 2))
Run Code Online (Sandbox Code Playgroud)

  • @AzamMirzaei - 将 `lead(...)` 的两个实例更改为 `lag(...)` (2认同)