R根据if-else语句选择行

R根据if-else语句选择行,r,if-statement,dataframe,subset,plyr,R,If Statement,Dataframe,Subset,Plyr,基于if-else条件限制数据集时遇到问题 这是我的数据帧的一个示例: mydf<-data.frame(chemical=c("Cd","Cd","Cd","Cd","Pb","Pb"),species=c("a","a","a","a","b","d"),scores=c(0,1,2,3,0,0)) 结束表应如下所示: chemical species scores 1 Cd a 1 2 Pb b 0 3

基于if-else条件限制数据集时遇到问题

这是我的数据帧的一个示例:

mydf<-data.frame(chemical=c("Cd","Cd","Cd","Cd","Pb","Pb"),species=c("a","a","a","a","b","d"),scores=c(0,1,2,3,0,0))
结束表应如下所示:

chemical species scores
1       Cd       a      1
2       Pb       b      0
3       Pb       d      0

这里使用OP的原始逻辑的可行解决方案,可能不是最优雅的代码

plyr

ddply(mydf,.(chemical,species),
           function(x) x[if(any(x$scores != 0)) {which.min(replace(x$scores, x$scores == 0, NA))} else which(x$scores == 0),])
mydf %>%
     group_by(chemical, species) %>%
     do(.[if(any(.$scores != 0)) {which.min(replace(.$scores, .$scores == 0, NA))} else which(.$scores == 0),])
dplyr

ddply(mydf,.(chemical,species),
           function(x) x[if(any(x$scores != 0)) {which.min(replace(x$scores, x$scores == 0, NA))} else which(x$scores == 0),])
mydf %>%
     group_by(chemical, species) %>%
     do(.[if(any(.$scores != 0)) {which.min(replace(.$scores, .$scores == 0, NA))} else which(.$scores == 0),])
Ifelse逻辑解包

# If none of the values are equal to 0
if(any(.$scores != 0))
# Find the index of the smallest values from a vector where 0 has been replaced by NA
{which.min(replace(.$scores, .$scores == 0, NA))} 
# Else find index of value equal to 0
else which(.$scores == 0)

这里使用OP的原始逻辑的可行解决方案,可能不是最优雅的代码

plyr

ddply(mydf,.(chemical,species),
           function(x) x[if(any(x$scores != 0)) {which.min(replace(x$scores, x$scores == 0, NA))} else which(x$scores == 0),])
mydf %>%
     group_by(chemical, species) %>%
     do(.[if(any(.$scores != 0)) {which.min(replace(.$scores, .$scores == 0, NA))} else which(.$scores == 0),])
dplyr

ddply(mydf,.(chemical,species),
           function(x) x[if(any(x$scores != 0)) {which.min(replace(x$scores, x$scores == 0, NA))} else which(x$scores == 0),])
mydf %>%
     group_by(chemical, species) %>%
     do(.[if(any(.$scores != 0)) {which.min(replace(.$scores, .$scores == 0, NA))} else which(.$scores == 0),])
Ifelse逻辑解包

# If none of the values are equal to 0
if(any(.$scores != 0))
# Find the index of the smallest values from a vector where 0 has been replaced by NA
{which.min(replace(.$scores, .$scores == 0, NA))} 
# Else find index of value equal to 0
else which(.$scores == 0)

这将实现您想要的:

library(tidyverse)
mydf %>%
  group_by(chemical, species) %>%
  mutate(zero = if_else(condition = max(scores)==0, true = TRUE, false = FALSE)) %>% 
  filter(scores==0&zero==TRUE|scores>0&zero==FALSE) %>% 
  arrange(chemical, species, scores) %>% 
  distinct(chemical, species, .keep_all = TRUE) %>% 
  select(-zero)

这将实现您想要的:

library(tidyverse)
mydf %>%
  group_by(chemical, species) %>%
  mutate(zero = if_else(condition = max(scores)==0, true = TRUE, false = FALSE)) %>% 
  filter(scores==0&zero==TRUE|scores>0&zero==FALSE) %>% 
  arrange(chemical, species, scores) %>% 
  distinct(chemical, species, .keep_all = TRUE) %>% 
  select(-zero)
我不知道这是否更快,但只是为了好玩,你也可以这样做

mydf %>% 
  group_by(chemical, species) %>% 
  summarize(scores = min(max(scores, 0)))
我不知道这是否更快,但只是为了好玩,你也可以这样做

mydf %>% 
  group_by(chemical, species) %>% 
  summarize(scores = min(max(scores, 0)))