这是一个数据集:
> 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> do3 of b3,然后排名==“2.4”。如果不是b2< do3 of b3,然后排名==“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)))})
这样可行,但数据集中只剩下物种和排名。如何正确编码以保持整个数据集的排名变化? 谢谢你的帮助。
答案 0 :(得分:1)
假设每个物种只有b3的一个值,你可以将这些值作为一个表,然后将它连接到另一个表,使你的比较简单,全部使用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)