给出以下数据框:
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创建rowwise
计算,该计算允许我在列C和D中summarize()
第一行 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行
答案 0 :(得分:4)
如果我理解正确,这就是你想要的:
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
答案 1 :(得分:4)
以下是使用dplyr
roll_sumr
和RcppRoll
的方法。您可以每5周使用ifelse
到mutate
B栏。为此,您可以使用A %% 5
,它是A列5的模数。当它为0时,您将前四周相加并按要求除以D / C. lag(roll_sumr(D,4)/roll_sumr(C,4)*100)
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)
答案 2 :(得分:3)
我不确定您的分析目标是什么,但是删除每个组中的四个数据行之一并将其替换为前一个组的摘要结果行似乎很奇怪。有关更多信息,请参阅以下其他选项。
要按组创建摘要,您可以执行以下操作:
df = df %>% mutate(group4 = (1:n() - 1) %/% 4) # Create groups of four consecutive rows
df %>%
group_by(group4) %>%
summarise(summary = sum(C)/sum(D))
group4 summary <dbl> <dbl> 1 0 1.063706 2 1 1.049375 3 2 1.057376
要插入摘要行,您可以执行以下操作,但随后您的数据将不会整洁,并且难以进行其他分析:
df = df %>% mutate(group4 = (1:n() - 1) %/% 4) # Create groups of four consecutive rows
df = bind_rows(df,
df %>%
group_by(group4) %>%
summarise(CD = sum(C)/sum(D))) %>%
arrange(group4)
A B C D group4 CD 1 1 92.44 14261 13183 0 NA 2 2 92.43 14244 13166 0 NA 3 3 94.24 14730 13882 0 NA 4 4 97.42 12149 11836 0 NA 5 NA NA NA NA 0 1.063706 6 5 94.75 14431 13674 1 NA 7 6 95.91 11038 10587 1 NA 8 7 95.66 14886 14240 1 NA 9 8 94.94 12587 11950 1 NA 10 NA NA NA NA 1 1.049375 11 9 94.27 13251 12492 2 NA 12 10 94.89 12789 12135 2 NA 13 NA NA NA NA 2 1.057376
您还可以将每个组的摘要添加为新列:
df = df %>%
mutate(group4 = (1:n() - 1) %/% 4) %>%
group_by(group4) %>%
mutate(CD = sum(C)/sum(D))
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
答案 3 :(得分:1)
修改了Scarabee的回答
d %>%
mutate(g1 = (A - 1)%/%5,
g2 = A%%5 == 0) %>%
group_by(g1) %>%
mutate(V = 100 * sum(D[!g2]/sum(C[!g2]))) %>%
ungroup() %>%
mutate(B = if_else(g2, round(V, 2), B)) %>%
select(-g1, -g2)
#> 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
答案 4 :(得分:1)
我知道您使用dplyr
询问了如何执行此操作,但这是另一个使用data.table
的选项。
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")