将函数应用于df1,该函数基于对df1每行的数据进行扩展和操作来创建新的df

时间:2019-06-03 02:04:56

标签: r function dataframe subset

我写了一个fxn(fxn-b),当我手动将其应用于df1的每一行时,它可以按预期工作。我想将fxn应用于df1,以便将其自动应用于df1的每一行。

每次迭代都应产生一个新的df,我希望通过rbind绑定新创建的df。当我尝试将fxn-b应用于df1时,它似乎只进入第一行。该错误消息还表明它没有经过df1的第1行。

顺便说一句,Fxn-b还包含另一个fxn(fxn-a),尽管我不认为这会影响结果。尽管如此,我会同时提供。

fxn-a:

pythag.opp.leg<-function(Radius){
Diam<-Radius*2
opposite<-sqrt((Diam^2)/2)
opposite.rounded<-round(opposite)
box<-opposite.rounded/2
return(box)
}    

fxn-b:

swc.fxn<-function(df1){
box<-pythag.opp.leg(df1$Radius)
box<-round(box)<
xHigh<-df1$X+box
Xlow<-df1$X-box
Yhigh<-df1$Y+box
Ylow<-df1$Y-box
swc.box<- data.frame(X=Xlow:Xhigh, Y=Ylow:Yhigh, Z=df1[1,3])
swc.box2<-expand(swc.box, X, Y, Z)
return(swc.box2)
} 

这是df1:

df1<-data.frame(X=c(100,110,120,130), Y=c(90,90,90,90), 
Z=c(10,10,15,15),Radius=c(2,2,2,2))

这是输出:

#A tibble: 25 x 3  
X     Y     Z  
<int> <int> <dbl>    
1    98    88    10  
2    98    89    10  
3    98    90    10  
4    98    91    10  
5    98    92    10  
6    99    88    10  
7    99    89    10  
8    99    90    10  
9    99    91    10  
10    99    92    10  
... with 15 more rows  
Warning messages:  
  1: In Xlow:Xhigh :  
  numerical expression has 4 elements: only the first used  
2: In Xlow:Xhigh :  
  numerical expression has 4 elements: only the first used  
3: In Ylow:Yhigh :  
  numerical expression has 4 elements: only the first used  
4: In Ylow:Yhigh :  
  numerical expression has 4 elements: only the first used  

1 个答案:

答案 0 :(得分:1)

如警告消息swc.fxn所述,只能处理一个输入。

swc.fxn(df1[1, ])

这行得通,但是如果您传递所有行,则行不通。一种方法是使用Map使其同时适用于多行,并使用lapplyexpand每个数据帧。

swc.fxn <-function(df1){
   box<-pythag.opp.leg(df1$Radius)
   box<-round(box)
   Xhigh<-df1$X+box
   Xlow<-df1$X-box
   Yhigh<-df1$Y+box
   Ylow<-df1$Y-box
   swc.box<- Map(function(a, b, c, d, e) data.frame(X = a:b, Y = c:d, Z = e), 
                Xlow, Xhigh, Ylow, Yhigh, df1$Z)
   swc.box2<- lapply(swc.box, function(x) tidyr::expand(x, X, Y, Z))
   return(swc.box2)
} 

这将为您返回每一行的数据框

swc.fxn(df1)
#[[1]]
# A tibble: 25 x 3
#      X     Y     Z
#    <int> <int> <dbl>
# 1    98    88    10
# 2    98    89    10
# 3    98    90    10
# 4    98    91    10
# 5    98    92    10
# 6    99    88    10
# 7    99    89    10
# 8    99    90    10
# 9    99    91    10
#10    99    92    10
# … with 15 more rows

#[[2]]
# A tibble: 25 x 3
#     X     Y     Z
#   <int> <int> <dbl>
# 1   108    88    10
# 2   108    89    10
# 3   108    90    10
# 4   108    91    10
# 5   108    92    10
# 6   109    88    10
# 7   109    89    10
# 8   109    90    10
# 9   109    91    10
#10   109    92    10
# … with 15 more rows
#.....
#.....

如果最终目标是使其成为一个数据帧,则可以将do.call(rbind...lapply一起使用,也可以使用purrr::map_df。该功能的简明版本可能是

swc.fxn <-function(df1){
   box<- round(pythag.opp.leg(df1$Radius))
   swc.box<- Map(function(a, b, c, d, e) data.frame(X = a:b, Y = c:d, Z = e), 
       df1$X-box, df1$X+box, df1$Y-box, df1$Y+box, df1$Z)
  swc.box2<- purrr::map_df(swc.box, function(x) tidyr::expand(x, X, Y, Z))
  return(swc.box2)
}