使用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")