Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用dplyr计算第n行自定义函数_R_Dataframe_Statistics_Mutate - Fatal编程技术网

使用dplyr计算第n行自定义函数

使用dplyr计算第n行自定义函数,r,dataframe,statistics,mutate,R,Dataframe,Statistics,Mutate,给定以下数据帧: A B C D 1 92.44 14261 13183 2 92.43 14244 13166 3 94.24 14730 13882 4 97.42 12149 11836 5 94.75 14431 13674 6 95.91 11038 10587 7 95.66 14886 14240 8 94.94 12587 11950 9 94.27

给定以下数据帧:

A   B        C       D
1   92.44   14261   13183
2   92.43   14244   13166
3   94.24   14730   13882
4   97.42   12149   11836
5   94.75   14431   13674
6   95.91   11038   10587
7   95.66   14886   14240
8   94.94   12587   11950
9   94.27   13251   12492
10  94.89   12789   12135
我尝试使用R创建行计算,它允许我总结C列和D列中的前4行,将它们相应地划分,并用下一行替换

replace(nth row + 1) = SUM(C) / SUM(D)
这是我试过的

df %>% mutate(B=replace(mpB, nrow(4)=summarise(C/D), NA))   
期望输出

A   B        C      D
1   92.44   14261   13183
2   92.43   14244   13166
3   94.24   14730   13882
4   97.42   12149   11836
5   94.01   14431   13674
6   95.91   11038   10587
7   95.66   14886   14240
8   94.94   12587   11950
9   94.27   13251   12492
10  95.18   12789   12135

*使用所需的计算更新第5行和第10行

我不确定您的分析目标是什么,但删除每组中的四个数据行中的一个,并将其替换为前一组的汇总结果行似乎有些奇怪。在等待更多信息之前,这里有一些其他选项

要按组创建摘要,可以执行以下操作:

df = df %>% mutate(group4 = (1:n() - 1) %/% 4) # Create groups of four consecutive rows

df %>% 
    group_by(group4) %>% 
    summarise(summary = sum(C)/sum(D))
您还可以将每个组的摘要添加为新列:

df = df %>% 
  mutate(group4 = (1:n() - 1) %/% 4) %>%
  group_by(group4) %>% 
  mutate(CD = sum(C)/sum(D))

如果我理解正确,这就是你想要的:

df %>% 
  mutate(group5 = (1:n() - 1) %/% 5) %>% # (using eipi10's method)
  group_by(group5) %>% 
  mutate(B = ifelse(row_number() == 5, # update only 5th row of each group
                    round(100 * sum(D[1:4]) / sum(C[1:4]), 2), 
                    B)) %>% 
  ungroup %>% 
  select(-group5)
# # A tibble: 10 × 4
#        A     B     C     D
#    <int> <dbl> <int> <int>
# 1      1 92.44 14261 13183
# 2      2 92.43 14244 13166
# 3      3 94.24 14730 13882
# 4      4 97.42 12149 11836
# 5      5 94.01 14431 13674
# 6      6 95.91 11038 10587
# 7      7 95.66 14886 14240
# 8      8 94.94 12587 11950
# 9      9 94.27 13251 12492
# 10    10 95.18 12789 12135

下面是如何使用来自RcppRoll的dplyr和roll_sumr实现这一点。您可以使用ifelse每5周对列B进行一次变异。为此,您可以使用%%5,它是A列乘以5的模。当值为0时,将前四周的总和除以要求的D/C。拉格罗尔苏姆德,4/罗尔苏姆尔,4*100

资料


修正斯卡拉比的答案

d%>% 突变1=A-1%/%5, g2=A%%5==0%>% 组别按1%>% mutateV=100*sumD[!g2]/sumC[!g2]]>% 解组%>% mutateB=如果其他项2,roundV,2,B%>% 选择-g1,-g2 >A、B、C、D > > 1 1 92.44 14261 13183 > 2 2 92.43 14244 13166 > 3 3 94.24 14730 13882 > 4 4 97.42 12149 11836 > 5 5 94.01 14431 13674 > 6 6 95.91 11038 10587 > 7 7 95.66 14886 14240 > 8 8 94.94 12587 11950 > 9 9 94.27 13251 12492 > 10 10 95.18 12789 12135
我知道您问过如何使用dplyr来实现这一点,但这里有另一个使用data.table的选项

结果:

     A     B     C     D
 1:  1 92.44 14261 13183
 2:  2 92.43 14244 13166
 3:  3 94.24 14730 13882
 4:  4 97.42 12149 11836
 5:  5 94.01 14431 13674
 6:  6 95.91 11038 10587
 7:  7 95.66 14886 14240
 8:  8 94.94 12587 11950
 9:  9 94.27 13251 12492
10: 10 95.18 12789 12135
使用以下方式生成的数据:

dat <- fread("A   B        C       D
1   92.44   14261   13183
2   92.43   14244   13166
3   94.24   14730   13882
4   97.42   12149   11836
5   94.75   14431   13674
6   95.91   11038   10587
7   95.66   14886   14240
8   94.94   12587   11950
9   94.27   13251   12492
10  94.89   12789   12135")

我不确定你们想要达到什么样的产出,但也许这是一个开始;df%>%mutategroup4=1:n-1%/%4%>%group4%>%summary=sumC/sumD@eipi10这有助于我开始,我如何获得分组的输出并使用mutate替换和更新下一行。即。。更新第5行和第10行,%%>%mutateB=replaceB?
       A     B     C     D group4       CD
 1     1 92.44 14261 13183      0 1.063706
 2     2 92.43 14244 13166      0 1.063706
 3     3 94.24 14730 13882      0 1.063706
 4     4 97.42 12149 11836      0 1.063706
 5     5 94.75 14431 13674      1 1.049375
 6     6 95.91 11038 10587      1 1.049375
 7     7 95.66 14886 14240      1 1.049375
 8     8 94.94 12587 11950      1 1.049375
 9     9 94.27 13251 12492      2 1.057376
10    10 94.89 12789 12135      2 1.057376
df %>% 
  mutate(group5 = (1:n() - 1) %/% 5) %>% # (using eipi10's method)
  group_by(group5) %>% 
  mutate(B = ifelse(row_number() == 5, # update only 5th row of each group
                    round(100 * sum(D[1:4]) / sum(C[1:4]), 2), 
                    B)) %>% 
  ungroup %>% 
  select(-group5)
# # A tibble: 10 × 4
#        A     B     C     D
#    <int> <dbl> <int> <int>
# 1      1 92.44 14261 13183
# 2      2 92.43 14244 13166
# 3      3 94.24 14730 13882
# 4      4 97.42 12149 11836
# 5      5 94.01 14431 13674
# 6      6 95.91 11038 10587
# 7      7 95.66 14886 14240
# 8      8 94.94 12587 11950
# 9      9 94.27 13251 12492
# 10    10 95.18 12789 12135
library(dplyr);library(RcppRoll)
df%>%
  mutate(B=ifelse(A %% 5 ==0,
                  lag(roll_sumr(D,4)/roll_sumr(C,4)*100),
                  B))

    A        B     C     D
1   1 92.44000 14261 13183
2   2 92.43000 14244 13166
3   3 94.24000 14730 13882
4   4 97.42000 12149 11836
5   5 94.01091 14431 13674
6   6 95.91000 11038 10587
7   7 95.66000 14886 14240
8   8 94.94000 12587 11950
9   9 94.27000 13251 12492
10 10 95.18373 12789 12135
df <- read.table(text="A   B        C       D
                 1   92.44   14261   13183
                 2   92.43   14244   13166
                 3   94.24   14730   13882
                 4   97.42   12149   11836
                 5   94.75   14431   13674
                 6   95.91   11038   10587
                 7   95.66   14886   14240
                 8   94.94   12587   11950
                 9   94.27   13251   12492
                 10  94.89   12789   12135",header=TRUE,stringsAsFactors=FALSE)
dat[, grp := rep(1:(dim(dat)[1]/5), each = 5)]
dat[, B := round(c(B[1:4], 100*sum(D[1:4])/sum(C[1:4])), 2), by = grp]
dat[, .(A, B, C, D)]
     A     B     C     D
 1:  1 92.44 14261 13183
 2:  2 92.43 14244 13166
 3:  3 94.24 14730 13882
 4:  4 97.42 12149 11836
 5:  5 94.01 14431 13674
 6:  6 95.91 11038 10587
 7:  7 95.66 14886 14240
 8:  8 94.94 12587 11950
 9:  9 94.27 13251 12492
10: 10 95.18 12789 12135
dat <- fread("A   B        C       D
1   92.44   14261   13183
2   92.43   14244   13166
3   94.24   14730   13882
4   97.42   12149   11836
5   94.75   14431   13674
6   95.91   11038   10587
7   95.66   14886   14240
8   94.94   12587   11950
9   94.27   13251   12492
10  94.89   12789   12135")