R使用函数循环遍历多个子组

时间:2018-06-11 14:29:14

标签: r loops data-manipulation

您好我正在尝试学习如何在数据框中循环多个组并应用某些算术运算。我没有编程背景,并且正在努力遍历多个条件。

我的数据如下所示:

Event = c(1,1,1,1,1,2,2,2,2,2)
Indiv1=c(4,5,6,11,45,66,8,9,32,45)
Indiv2=c(7,81,91,67,12,34,56,78,90,12)
Category=c(1,1,2,2,2,1,2,2,1,1) 
Play_together=c(1,0,1,1,1,1,1,1,0,1)
Money=c(23,11,78,-9,-12,345,09,43,21,90)
z = data.frame(Event,Indiv1,Indiv2,Category,Play_together,Money)

我想要查看每个事件和每个类别,并在Play_together == 1的情况下获取Money的平均值。当Play_together == 0时,我想申请Money / 100。< / p>

我理解循环看起来如下:

 for i in 1:nrow(z){
     #loop for event{
         #loop for Category{
              #Define avg or division function
         }
     }
 }

但是,我似乎无法使用嵌套循环实现此功能。我看到了另一篇使用dplyr包的帖子(链接:apply function for each subgroup)。我想知道是否有人可以帮助我在不使用任何软件包的情况下实现这一点(我知道与使用R软件包相比,这可能需要更长的时间)。我正在尝试学习R,这是我第一次使用嵌套循环。

最终输出如下所示: enter image description here

对于事件1,以下是:

a)对于cateory 1:

第一行

Play_together == 1;我们采用平均货币价值,因此最终产出= 23/1 = 23

第2行中的Play_together == 0;我们拿Money / 100 = 0.11

b)对于第2类: 所有观察结果的Play_together == 1。我们为所有三次观察采取平均金钱。

这与事件2类似。在我的实际数据集中,我有事件= 600,类别数量范围从1到10.有些事件可能只有1个类别,最多10个类别。所以任何功能都需要非常灵活。我的数据集中的观察总数约为150万,因此循环过程中的任何更改都可以减少执行操作所需的时间(尽管在此阶段我的优先级是循环过程本身)。 / p>

如果您能告诉我如何使用嵌套循环并简要解释步骤,那将再次提供帮助。非常感谢。

2 个答案:

答案 0 :(得分:2)

会这样吗? 我知道它使用的是dplyr,但是这个包是为这种工作而制作的; - )

Event = c(1,1,1,1,1,2,2,2,2,2)
Indiv1=c(4,5,6,11,45,66,8,9,32,45)
Indiv2=c(7,81,91,67,12,34,56,78,90,12)
Category=c(1,1,2,2,2,1,2,2,1,1) 
Play_together=c(1,0,1,1,1,1,1,1,0,1)
Money=c(23,11,78,-9,-12,345,09,43,21,90)
z = data.frame(Event,Indiv1,Indiv2,Category,Play_together,Money)

library(dplyr)

df_temp <- z %>%
  group_by( Event, Category, Play_together ) %>%
  summarise( money_mean = mean( Money ) ) %>%
  mutate( final_output = ifelse( Play_together == 0, money_mean / 100, money_mean )) %>%
  select( -money_mean )

df <- z %>%
  left_join(df_temp, by = c("Event", "Category", "Play_together" )) %>%
  arrange(Event, Category)

答案 1 :(得分:1)

考虑基础R bytapply的面向对象的包装器,用于按因子子集数据帧,但与split不同,可以将子集传递给定义的函数。然后,使用ifelse Final_Output 字段运行条件逻辑。最后,为最终对象堆叠所有子集化的数据帧。

# LIST OF DATAFRAMES
by_list <- by(z, z[c("Event", "Category")], function(sub) {      
  tmp <- subset(sub, Play_together==1)
  sub$Final_Output <- ifelse(sub$Play_together == 1, mean(tmp$Money), sub$Money/100)
  return(sub)      
})

# APPEND ALL DATAFRAMES
final_df <- do.call(rbind, by_list)    
row.names(final_df) <- NULL

final_df 
#    Event Indiv1 Indiv2 Category Play_together Money Final_Output
# 1      1      4      7        1             1    23        23.00
# 2      1      5     81        1             0    11         0.11
# 3      2     66     34        1             1   345       217.50
# 4      2     32     90        1             0    21         0.21
# 5      2     45     12        1             1    90       217.50
# 6      1      6     91        2             1    78        19.00
# 7      1     11     67        2             1    -9        19.00
# 8      1     45     12        2             1   -12        19.00
# 9      2      8     56        2             1     9        26.00
# 10     2      9     78        2             1    43        26.00