如何根据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
我有一个我认为很简单的问题,但我想不出来!我有一个包含多列的数据框。这是一个一般示例:
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