Примените функцию к df1, которая создает новый df на основе расширения и манипулирования данными из каждой строки df1 - PullRequest
0 голосов
/ 03 июня 2019

Я написал fxn (fxn-b), который работает как положено, когда я вручную применяю его к каждой строке df1. Я хотел бы применить fxn к df1, чтобы он автоматически применялся к каждой строке df1.

Каждая итерация должна создавать новый df, и я хотел бы, чтобы вновь созданные dfs были связаны через rbind. Когда я пытаюсь применить fxn-b к df1, кажется, что он попадает только в первый ряд. Сообщение об ошибке также указывает на то, что оно не прогрессирует после строки 1 в df1.

Кстати, Fxn-b также содержит другой fxn (fxn-a), хотя я не верю, что это влияет на результат. Тем не менее я предоставлю оба.

FXN-а:

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

FXN-б:

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 Ответ

1 голос
/ 03 июня 2019

Как упомянуто в предупреждающем сообщении swc.fxn может обрабатывать только один ввод.

swc.fxn(df1[1, ])

Это работает, но если вы пропустите все строки, это не сработает.Один из способов - использовать Map, чтобы он работал для нескольких строк одновременно, и использовать от lapply до expand каждого кадра данных.

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)
} 
...