我正在嘗試計算幾個年級之間的累積時間。
這是我原來的df樣子:
df = data.frame(id = c(1,1,1,1,2,2,2,2),
group = c(0,0,0,0,1,1,1,1),
grade = c(0,1,2,3,0,1,3,4),
time = c(10,7,4,1,20,17,14,11))
這是我所期望的結果df1:
df1 = df %>%
pivot_wider(
names_from = "grade",
names_prefix = "grade_",
values_from = "time") %>%
replace(is.na(.), 0) %>%
mutate(grade_1 = grade_1 grade_2 grade_3 grade_4,
grade_2 = grade_2 grade_3 grade_4,
grade_3 = grade_3 grade_4) %>%
pivot_longer(
cols = 3:7,
names_to = "grade",
names_prefix = "grade_",
values_to = "time")
我的方法有效,但我希望它更靈活。當我在df中有更多成績時,我不需要手動添加grade_x = Grade_1 Grade_2 Grade_3 ...
謝謝!
uj5u.com熱心網友回復:
一種選擇是重新排列grade列(不包括第一行,其中grade == 0,然后這樣做cumsum是相反的。然后,我們可以按所需的順序重新排列。
library(tidyverse)
results <- df %>%
group_by(id, grp2 = ifelse(grade == 0, 0, 1)) %>%
arrange(id, desc(grade)) %>%
mutate(time = cumsum(time)) %>%
ungroup(grp2) %>%
select(-grp2) %>%
arrange(id, grade) %>%
ungroup
輸出
id group grade time
<dbl> <dbl> <dbl> <dbl>
1 1 0 0 10
2 1 0 1 12
3 1 0 2 5
4 1 0 3 1
5 2 1 0 20
6 2 1 1 42
7 2 1 3 25
8 2 1 4 11
如果您需要每個組的行數與所需輸出中的行數相同,則可以使用complete:
df %>%
tidyr::complete(id, grade) %>%
group_by(id) %>%
fill(group, .direction ="downup") %>%
replace(is.na(.), 0) %>%
group_by(id, grp2 = ifelse(grade == 0, 0, 1)) %>%
arrange(id, desc(grade)) %>%
mutate(time = cumsum(time)) %>%
ungroup(grp2) %>%
select(-grp2) %>%
arrange(id, grade) %>%
ungroup
輸出
id grade group time
<dbl> <dbl> <dbl> <dbl>
1 1 0 0 10
2 1 1 0 12
3 1 2 0 5
4 1 3 0 1
5 1 4 0 0
6 2 0 1 20
7 2 1 1 42
8 2 2 1 25
9 2 3 1 25
10 2 4 1 11
或者,如果您想來回旋轉,則可以執行以下操作:
output <- df %>%
pivot_wider(
names_from = "grade",
names_prefix = "grade_",
values_from = "time") %>%
replace(is.na(.), 0) %>%
select(id, group, grade_0, last_col():grade_1)
results2 <- output %>%
select(-c(id, group, grade_0)) %>%
rowwise()%>%
do(data.frame(t(cumsum(unlist(.))))) %>%
bind_cols(select(output, id, group, grade_0), .) %>%
pivot_longer(
cols = 3:7,
names_to = "grade",
names_prefix = "grade_",
values_to = "time")
uj5u.com熱心網友回復:
第一次嘗試:
對于跨變數的累積總和,我們可以 group_by 并使用 cumsum() :無需指定等級等。如果需要,您可以進行更多聚合。
df%>%
group_by(grade)%>%
mutate(Cum_Time = cumsum(time))%>%arrange(grade)
id group grade time Cum_Time
<dbl> <dbl> <dbl> <dbl> <dbl>
1 1 0 0 10 10
2 2 1 0 20 30
3 1 0 1 7 7
4 2 1 1 17 24
5 1 0 2 4 4
6 1 0 3 1 1
7 2 1 3 14 15
8 2 1 4 11 11
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/450200.html
標籤:r
下一篇:在R中添加散點圖
