在 R 中使用替换 plyr 或 dplyr 的多个条件
Multiple conditions using replace plyr or dplyr in R
这是一个数据集:
> mydat
species section obs doy ranking
A A1 b1 123 2.1
A A2 b2 135 2.2
A A3 b3 147 2.3
B A1 b2 124 2.2
B A2 b3 132 2.3
B A3 b2 145 2.2
C A1 b1 120 2.1
C A2 b3 133 2.3
C A3 b2 137 2.2
我正在尝试编码;对于 obs==b2 的每个物种,如果 b2 的 doy > b3 的 doy,则排名 ==“2.4”。如果 b2 的 doy < b3 的 doy,那么排名=“2.2”(保持不变),所以我得到这个结果:
> mydat2
species section obs doy ranking
A A1 b1 123 2.1
A A2 b2 135 2.2
A A3 b3 147 2.3
B A1 b2 124 2.2
B A2 b3 132 2.3
B A3 b2 145 2.4
C A1 b1 120 2.1
C A2 b3 133 2.3
C A3 b2 137 2.4
我使用包 plyr 来避免循环,因为我发现循环很难理解。我知道现在很多人使用 dplyr 而不是 plyr,所以我很高兴得到使用 plyr 或 dplyr 的答案。
这是我笨拙的尝试:
require (plyr)
mydat2 <- ddply(.data=mydat,
.variables=c("species"),
function(x){
return(data.frame(replace(x$ranking, x$doy[x$obs=='b2']>x$doy[x$obs=="b3"],2.4)))})
这可行,但数据集中只剩下物种和排名。我如何正确编码以保持整个数据集的排名变化?
谢谢你的帮助。
假设每个物种只有一个 b3 的 doy 值,您可以将这些值作为单个值 table,然后将其与另一个 table 合并以简化比较,全部使用dplyr
:
library(dplyr)
# get a single doy value for each species
b3values <- mydat %>%
filter(obs == 'b3') %>%
group_by(species) %>%
summarize(
# using min(doy) but if there's only one value, you could use any grouping function like sum, max, etc
b3doy = min(doy)
)
# join b3values to your original data
mydat2 <- mydat %>%
left_join(b3values, by = 'species') %>%
mutate(
# use case_when() to lay out your conditions and the values you want
ranking = case_when(
obs == 'b2' & (doy > b3doy) ~ 2.4
, obs == 'b2' & (doy < b3doy) ~ 2.2
# default value is to keep the ranking as-is
, T ~ ranking
)
) %>%
# optionally, drop the extra b3doy column
select(-b3doy)
这是一个数据集:
> mydat
species section obs doy ranking
A A1 b1 123 2.1
A A2 b2 135 2.2
A A3 b3 147 2.3
B A1 b2 124 2.2
B A2 b3 132 2.3
B A3 b2 145 2.2
C A1 b1 120 2.1
C A2 b3 133 2.3
C A3 b2 137 2.2
我正在尝试编码;对于 obs==b2 的每个物种,如果 b2 的 doy > b3 的 doy,则排名 ==“2.4”。如果 b2 的 doy < b3 的 doy,那么排名=“2.2”(保持不变),所以我得到这个结果:
> mydat2
species section obs doy ranking
A A1 b1 123 2.1
A A2 b2 135 2.2
A A3 b3 147 2.3
B A1 b2 124 2.2
B A2 b3 132 2.3
B A3 b2 145 2.4
C A1 b1 120 2.1
C A2 b3 133 2.3
C A3 b2 137 2.4
我使用包 plyr 来避免循环,因为我发现循环很难理解。我知道现在很多人使用 dplyr 而不是 plyr,所以我很高兴得到使用 plyr 或 dplyr 的答案。 这是我笨拙的尝试:
require (plyr)
mydat2 <- ddply(.data=mydat,
.variables=c("species"),
function(x){
return(data.frame(replace(x$ranking, x$doy[x$obs=='b2']>x$doy[x$obs=="b3"],2.4)))})
这可行,但数据集中只剩下物种和排名。我如何正确编码以保持整个数据集的排名变化? 谢谢你的帮助。
假设每个物种只有一个 b3 的 doy 值,您可以将这些值作为单个值 table,然后将其与另一个 table 合并以简化比较,全部使用dplyr
:
library(dplyr)
# get a single doy value for each species
b3values <- mydat %>%
filter(obs == 'b3') %>%
group_by(species) %>%
summarize(
# using min(doy) but if there's only one value, you could use any grouping function like sum, max, etc
b3doy = min(doy)
)
# join b3values to your original data
mydat2 <- mydat %>%
left_join(b3values, by = 'species') %>%
mutate(
# use case_when() to lay out your conditions and the values you want
ranking = case_when(
obs == 'b2' & (doy > b3doy) ~ 2.4
, obs == 'b2' & (doy < b3doy) ~ 2.2
# default value is to keep the ranking as-is
, T ~ ranking
)
) %>%
# optionally, drop the extra b3doy column
select(-b3doy)