如何根据r中for循环中的条件计算均值

how to calculate mean based on conditions in for loop in r

我有一个我认为很简单的问题,但我想不出来!我有一个包含多列的数据框。这是一个一般示例:

colony = c('29683','25077','28695','4865','19858','2235','1948','1849','2370','23196')
age = c(21,23,4,25,7,4,12,14,9,7)
activity = c(19,45,78,33,2,49,22,21,112,61)
test.df = data.frame(colony,age,activity)
test.df

我想让 R 根据数据框中的菌落年龄计算平均值 activity。具体来说,我希望它只计算与该行中的菌落年龄相同或更老的菌落的平均值 activity,不包括该行中菌落的 activity。例如,殖民地 29683 是 21 岁。对于我的这一行数据,我想要平均 activity 个超过 21 岁的菌落。这将包括殖民地 25077 和殖民地 4865;平均值为 (45+33)/2 = 39。我希望 R 通过识别当前行中菌落的年龄,然后识别比该菌落更老的菌落,来为每一行数据执行此操作,然后对这些菌落的 activity 进行平均。

我已经尝试在 R 中的 for 循环中执行此操作。这是我使用的代码:

test.avg = vector("numeric",nrow(test.df))`
for (i in 1:10){ 
test.avg[i] <- mean(subset(test.df$activity,test.df$age >= age[i])[-i])
}

R returns 一个值列表,其中一半是正确的,另一半是错误的(我什至不确定它是如何计算出那些不正确的数字的……)。与它们在数据框中列出的方式相比,正确的数字也是乱序的。它显然能够为循环的某些迭代做正确的事情,但不是全部。如果有人能帮我解决我的代码,我将不胜感激!

您可以使用 map_df :

  library(tidyverse)
  test.df  %>% 
        mutate(map_df(1:nrow(test.df), ~
                     test.df %>% 
                     filter(age >= test.df$age[.x]) %>% 
                     summarise(av_acti= mean(activity))))

您的解决方案中的问题是索引将应用于原始 data.frame,但您对其进行子集化,因此它不再匹配。

尝试这样的事情:首先找到最小年龄,然后排除当前索引并计算年龄 >= 预先计算的最小年龄的案例的平均值 activity。

for (i in 1:10){ 
  test.avg[i] <- {amin=age[i]; mean(subset(test.df[-i,], age >= amin)$activity)}
}
colony = c('29683','25077','28695','4865','19858','2235','1948','1849','2370','23196')
age = c(21,23,4,25,7,4,12,14,9,7)
activity = c(19,45,78,33,2,49,22,21,112,61)
test.df = data.frame(colony,age,activity)

library(tidyverse)
test.df %>% 
  mutate(result = map_dbl(age, ~mean(activity[age > .x])))
#>    colony age activity   result
#> 1   29683  21       19 39.00000
#> 2   25077  23       45 33.00000
#> 3   28695   4       78 39.37500
#> 4    4865  25       33      NaN
#> 5   19858   7        2 42.00000
#> 6    2235   4       49 39.37500
#> 7    1948  12       22 29.50000
#> 8    1849  14       21 32.33333
#> 9    2370   9      112 28.00000
#> 10  23196   7       61 42.00000

# base
test.df$result <- with(test.df, sapply(age, FUN = function(x) mean(activity[age > x])))
                         
test.df 
#>    colony age activity   result
#> 1   29683  21       19 39.00000
#> 2   25077  23       45 33.00000
#> 3   28695   4       78 39.37500
#> 4    4865  25       33      NaN
#> 5   19858   7        2 42.00000
#> 6    2235   4       49 39.37500
#> 7    1948  12       22 29.50000
#> 8    1849  14       21 32.33333
#> 9    2370   9      112 28.00000
#> 10  23196   7       61 42.00000

reprex package (v1.0.0)

创建于 2021-03-22