我有两个数据框。 Df1有两列:设施的ID列和指定有权使用该设施的农场数量的列。 Df2有3列,一列具有设施的ID列,一列具有农场ID,第三列具有该农场与设施之间的距离。 Df2目前为每个设施列出了太多的农场。
我需要做的是过滤掉那些有权使用该设施的人。将有不同数量的农场有权使用每个设施,他们将始终是最接近它的人。
以下示例数据
DF1
cgID number.of.farms
1 1 5
2 2 3
3 3 1
4 4 6
DF2 (EXTRACT)
cgID FarmID Distance
1 farm1 0.01
1 farm2 0.02
1 farm3 0.03
1 farm4 0.04
1 farm5 0.05
1 farm6 0.06
1 farm7 0.07
1 farm8 0.08
2 farm9 0.01
2 farm10 0.02
2 farm11 0.03
2 farm12 0.04
2 farm13 0.05
2 farm14 0.06
2 farm15 0.07
2 farm16 0.08
我目前只能使用以下代码单独为每个设施实现我的目标:
tempdata1<- subset(Df2, Df2$cgID==Df1$cgID[1]) #Select farms connected to the facility
editdata1<- tempdata1[1:Df1$number.of.farms[1],] #Filter out the 5 closest farms to the facility (5 was derived from Df1)
我需要为此设置1300个设施,因此我需要为每个设施运行这些行,并将所有过滤后的数据分组到一个数据帧中。我试过通过运行for循环或编写函数来尝试这样做,但两者都没有工作。下面是让我最接近我想要的代码:
r<- sum(Df1$number.of.farms)#number of rows needed in final dataframe
c<- ncol(Df2) #number of columns needed in final dataframe
n<- nrow(Df1) #number of rows needed to go through in the for loop
d<- data.frame()
for (i in 1:n)
{
tempdata[i]<- subset(Df2,Df2$cgID==Df1$cgID[i])
editdata<- tempdata[1:Df1$number.of.farms[i],]
d[[i]]<- editdata
}
do.call(rbind,)
答案 0 :(得分:0)
您可以使用library(dplyr)
# Change column name of DF1$number.of.farms to DF1$numfarms
DF1 <- DF1 %>% # %>% chains actions (verbs) together
setNames("cgID","numfarms") # renames columns
expected <- DF2 %>%
left_join(., DF1, by="cgID") %>% # merges data frames by cgID column; `.` specifies object that was piped from chaining
group_by(cgID) %>% # you want to perform following actions group-wise
arrange(Distance) %>% # sort in ascending order, use `desc(Distance)` for descending order
do(head(.,unique(.$numfarms))) # select top N rows specified, `do` will operate group-wise
iris <- as.data.table(iris)
iris <- iris[,lapply(.SD,mean), by=Species]