带 ddply 函数的 if 语句

if statement with ddply function

我正在尝试将 if 语句与 ddply 一起使用,但 if 语句有问题。

示例数据集是:

data<-data.frame(Gear=c(rep("S",10),rep("C",10)),TowSurvey=c(0,0,1,1,0,1,1,1,1,0),TowCom=c(0,1,1,1,0,1,1,1,1,0),
    StationID=c(1,2,3,4,5,6,7,8,9,10),Totwght=c(2,8,6,4,12,9,56,7,89,10),Totexpwght=c(5,8,12,45,89,56,23,78,56,41),
    Expnum=c(1,5,6,98,45,2,6,3,7,45),Exp=c(56,25,85,74,1,23,56,45,89,75))

我的第一次尝试是

if(data$Gear=="S" & data$TowSurvey== 1 | data$Gear=="C" & data$TowCom== 1){
    datad<-ddply(data, .(StationID,Gear), summarize,Totwghtpertow=sum(Totwght),
    Totexppertow=sum(Totexpwght),Totnum =sum(Expnum),Totexpnum=sum(Exp))}
print(datad)

但是不满足if语句条件的记录都包含在datad中。

然后我发现了这个 post:聚合(计数)符合条件的行,按唯一值分组。 Aggregate (count) rows that match a condition, group by unique values

所以我根据 post 的回答进行的第二次尝试是

datad<-ddply(data, .(StationID,Gear), summarize,Totwghtpertow=sum(Totwght[Gear=="S" & TowSurvey== 1 | Gear=="C" & TowCom== 1]))

我只尝试使用一列作为测试并得到相同的结果。在尝试解决这个问题时,我们将不胜感激。 谢谢

如果您 运行 是第一次尝试,您实际上应该会收到一条错误消息,因为 if 只能计算长度为 1 的逻辑向量。

你真的不需要 if 语句。子集你的数据就可以了。

data_sub <- subset(data, (data$Gear=="S" & data$TowSurvey== 1) | (data$Gear=="C" & data$TowCom== 1))

您可以 运行 您的 ddply 语句使用 data_sub 而不是 data

或者,如果您要大量使用,可以将其包装在一个函数中:

datad_func <- function(data){
data_sub <- subset(data, (data$Gear=="S" & data$TowSurvey== 1) | (data$Gear=="C" & data$TowCom== 1))
datad<-ddply(data_sub, .(StationID,Gear), summarize,Totwghtpertow=sum(Totwght),
             Totexppertow=sum(Totexpwght),Totnum =sum(Expnum),Totexpnum=sum(Exp))
rm('data_sub')
print(datad)
}

datad_func(data)

   StationID Gear Totwghtpertow Totexppertow Totnum Totexpnum
1          2    C             8            8      5        25
2          3    C             6           12      6        85
3          3    S             6           12      6        85
4          4    C             4           45     98        74
5          4    S             4           45     98        74
6          6    C             9           56      2        23
7          6    S             9           56      2        23
8          7    C            56           23      6        56
9          7    S            56           23      6        56
10         8    C             7           78      3        45
11         8    S             7           78      3        45
12         9    C            89           56      7        89
13         9    S            89           56      7        89

plyr 不太擅长在函数中进行子集化,因此您可以像@scribbles 所说的那样在之前或之后进行。

您也可以尝试 dplyr 并将它们放在一起:

library(dplyr)
data %>% filter((data$Gear == "S" & data$TowSurvey == 1) | (data$Gear == "C" & data$TowCom == 1)) %>%
         group_by(StationID, Gear) %>% 
         summarise_each(funs(sum), Totwght, Totexpwght, Expnum, Exp)