问题描述
那里! 我有 data.frame 看起来像:
date id s int
1 2021-01-01 1 A 1
2 2021-05-03 1 B 1
3 2021-05-05 1 C 1
4 2021-05-02 2 A 1
5 2021-06-01 2 A 1
6 2021-02-01 2 B 1
7 2021-03-02 3 C 1
8 2021-06-01 3 C 1
我需要用重新计算的值添加两列:
所以,结果是:
date id s int int1 int2
1 2021-01-01 1 A 1 0 0.33
2 2021-05-03 1 B 1 1 0.33
3 2021-05-05 1 C 1 0 0.33
4 2021-05-02 2 A 1 0 0.33
5 2021-06-01 2 A 1 1 0.33
6 2021-02-01 2 B 1 0 0.33
7 2021-03-02 3 C 1 0 0.50
8 2021-06-01 3 C 1 1 0.50
我知道如何用“for”循环来解决它,但这对于大数据来说会减慢速度。 我知道“mutate”,但还是不明白,请帮忙举个例子。
我的数据:
t <- data.frame(date=c('2021-01-01','2021-05-03','2021-05-05','2021-05-02','2021-06-01','2021-02-01','2021-03-02','2021-06-01'),id=c('1','1','2','3','3'),s=c('A','B','C','A','C'),int=c('1','1')
)
解决方法
你在哪个数据库上?所以你想要 sql 更新命令?
,我希望我能正确理解您要做什么:
由于有不同的可能情况,我认为最简单的方法是根据“s”变量的不同可能性拆分可初始化表。
- 1:仅非 C
- 2:只有 C;
- 3:非 C 和 C 的混合体;
然后使用 mutate 创建您想要的两列,并将它们重新组合在一起。
library(tidyverse)
t1 <- t %>%
group_by(id)%>%
mutate(id_row = row_number())%>%
filter(!("C" %in% s)) %>%
mutate(id1 = ifelse(id_row==max(id_row),1,0),id2 = round(1/n(),2))
t2 <- t %>%
group_by(id)%>%
mutate(id_row = row_number())%>%
filter(length(unique(s))==1 & s=="C")%>%
mutate(id1 = ifelse(id_row==max(id_row),2))
t3 <- t %>%
group_by(id)%>%
filter(length(unique(s))>1 & "C" %in% s)%>%
mutate(id_row = ifelse(s!="C",row_number(),NA),id1 = case_when(
id_row==max(id_row,na.rm = TRUE)~1,TRUE~0),2))
t <- bind_rows(t1,t2,t3) %>%
select(-id_row) %>%
arrange(id,s)
t
# A tibble: 8 x 6
# Groups: id [3]
date id s int id1 id2
<chr> <chr> <chr> <chr> <dbl> <dbl>
1 2021-01-01 1 A 1 0 0.33
2 2021-05-03 1 B 1 1 0.33
3 2021-05-05 1 C 1 0 0.33
4 2021-05-02 2 A 1 0 0.33
5 2021-06-01 2 A 1 0 0.33
6 2021-02-01 2 B 1 1 0.33
7 2021-03-02 3 C 1 0 0.5
8 2021-06-01 3 C 1 1 0.5