如何基于R中分组数据集中的二进制变量创建新变量?
数据集有3列,第一列为“id”,第二列为“年”,第三列为“节点”。第三列是一个二进制变量。现在,我们需要使用如下规则修复第3列“节点”上的数据错误 1) 在每个id中,节点=1的最后一个值之前的所有值都应等于1。在节点=1之前不应出现节点=0。它应该在所有年份都只停留在node=1,或者在某个点从node=1转到node=0 2) 在每个id中,如果从year1到year8的节点的所有值都等于(0或1),那么我们必须保持它们不变 总之,校正后的数据集应该如下所示如何基于R中分组数据集中的二进制变量创建新变量?,r,rolling-computation,R,Rolling Computation,数据集有3列,第一列为“id”,第二列为“年”,第三列为“节点”。第三列是一个二进制变量。现在,我们需要使用如下规则修复第3列“节点”上的数据错误 1) 在每个id中,节点=1的最后一个值之前的所有值都应等于1。在节点=1之前不应出现节点=0。它应该在所有年份都只停留在node=1,或者在某个点从node=1转到node=0 2) 在每个id中,如果从year1到year8的节点的所有值都等于(0或1),那么我们必须保持它们不变 总之,校正后的数据集应该如下所示 id node y
id node year
383100111 1 1
383100111 1 2
383100111 1 3
383100111 1 4
383100111 1 5
383100111 1 6
383100111 1 7
383100111 0 8
383100222 1 1
383100222 1 2
383100222 1 3
383100222 1 4
383100222 1 5
383100222 1 6
383100222 1 7
383100222 1 8
383100333 1 1
383100333 1 2
383100333 1 3
383100333 1 4
383100333 1 5
383100333 1 6
383100333 1 7
383100333 1 8
383100444 1 1
383100444 1 2
383100444 1 3
383100444 1 4
383100444 1 5
383100444 1 6
383100444 1 7
383100444 0 8
383100555 1 1
383100555 1 2
383100555 1 3
383100555 1 4
383100555 1 5
383100555 1 6
383100555 1 7
383100555 1 8
383100666 0 1
383100666 0 2
383100666 0 3
383100666 0 4
383100666 0 5
383100666 0 6
383100666 0 7
383100666 0 8
383100777 1 1
383100777 1 2
383100777 1 3
383100777 1 4
383100777 1 5
383100777 1 6
383100777 1 7
383100777 1 8
包含错误的原始数据集的结构如下:
structure(list(id = c(383100111, 383100111, 383100111, 383100111,
383100111, 383100111, 383100111, 383100111, 383100222, 383100222,
383100222, 383100222, 383100222, 383100222, 383100222, 383100222,
383100333, 383100333, 383100333, 383100333, 383100333, 383100333,
383100333, 383100333, 383100444, 383100444, 383100444, 383100444,
383100444, 383100444, 383100444, 383100444, 383100555, 383100555,
383100555, 383100555, 383100555, 383100555, 383100555, 383100555,
383100666, 383100666, 383100666, 383100666, 383100666, 383100666,
383100666, 383100666, 383100777, 383100777, 383100777, 383100777,
383100777, 383100777, 383100777, 383100777), node = c(1, 1, 1,
0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1,
0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1), year = c(1, 2, 3, 4, 5, 6,
7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3,
4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8,
1, 2, 3, 4, 5, 6, 7, 8)), row.names = c(NA, 56L), class ="data.frame")->dataframe
谢谢大家! 试试这段代码
library(tidyverse)
df_repaired <- df %>% group_by(id) %>%
mutate(col1 = cumsum(node)) %>%
mutate(node2 = ifelse(last(col1)==col1 & node == 0, 0, 1)) %>%
ungroup() %>%
select(-col1, -node) %>%
rename(node = node2)
> df_repaired
# A tibble: 56 x 3
id year node
<dbl> <dbl> <dbl>
1 383100111 1 1
2 383100111 2 1
3 383100111 3 1
4 383100111 4 1
5 383100111 5 1
6 383100111 6 1
7 383100111 7 1
8 383100111 8 0
9 383100222 1 1
10 383100222 2 1
# ... with 46 more rows
另一个可能更容易理解的策略
library(tidyverse)
df_repaired <- df %>% group_by(id) %>%
mutate(dummy_id = row_number(),
col1 = last(which(node ==1)),
node2 = ifelse(dummy_id > col1 | is.na(col1), 0, 1)) %>%
ungroup() %>%
select(-node, -dummy_id, -col1) %>%
rename(node = node2)
> print(df_repaired, n=56)
# A tibble: 56 x 3
id year node
<dbl> <dbl> <dbl>
1 383100111 1 1
2 383100111 2 1
3 383100111 3 1
4 383100111 4 1
5 383100111 5 1
6 383100111 6 1
7 383100111 7 1
8 383100111 8 0
9 383100222 1 1
10 383100222 2 1
11 383100222 3 1
12 383100222 4 1
13 383100222 5 1
14 383100222 6 1
15 383100222 7 1
16 383100222 8 1
17 383100333 1 1
18 383100333 2 1
19 383100333 3 1
20 383100333 4 1
21 383100333 5 1
22 383100333 6 1
23 383100333 7 1
24 383100333 8 1
25 383100444 1 1
26 383100444 2 1
27 383100444 3 1
28 383100444 4 1
29 383100444 5 1
30 383100444 6 1
31 383100444 7 1
32 383100444 8 0
33 383100555 1 1
34 383100555 2 1
35 383100555 3 1
36 383100555 4 1
37 383100555 5 1
38 383100555 6 1
39 383100555 7 1
40 383100555 8 1
41 383100666 1 0
42 383100666 2 0
43 383100666 3 0
44 383100666 4 0
45 383100666 5 0
46 383100666 6 0
47 383100666 7 0
48 383100666 8 0
49 383100777 1 1
50 383100777 2 1
51 383100777 3 1
52 383100777 4 1
53 383100777 5 1
54 383100777 6 1
55 383100777 7 1
56 383100777 8 1
库(tidyverse)
df_已修复%group_by(id)%%>%
变异(伪id=行号(),
col1=last(其中(节点==1)),
node2=ifelse(伪id>col1 | is.na(col1),0,1))%>%
解组()%>%
选择(-node,-dummy_id,-col1)%>%
重命名(节点=节点2)
>打印(df_已修复,n=56)
#A tibble:56 x 3
id年份节点
1 383100111 1 1
2 383100111 2 1
3 383100111 3 1
4 383100111 4 1
5 383100111 5 1
6 383100111 6 1
7 383100111 7 1
8 383100111 8 0
9 383100222 1 1
10 383100222 2 1
11 383100222 3 1
12 383100222 4 1
13 383100222 5 1
14 383100222 6 1
15 383100222 7 1
16 383100222 8 1
17 383100333 1 1
18 383100333 2 1
19 383100333 3 1
20 383100333 4 1
21 383100333 5 1
22 383100333 6 1
23 383100333 7 1
24 383100333 8 1
25 383100444 1 1
26 383100444 2 1
27 383100444 3 1
28 383100444 4 1
29 383100444 5 1
30 383100444 6 1
31 383100444 7 1
32 383100444 8 0
33 383100555 1 1
34 383100555 2 1
35 383100555 3 1
36 383100555 4 1
37 383100555 5 1
38 383100555 6 1
39 383100555 7 1
40 383100555 8 1
41 383100666 1 0
42 383100666 2 0
43 383100666 3 0
44 383100666 4 0
45 383100666 5 0
46 383100666 6 0
47 383100666 7 0
48 383100666 8 0
49 383100777 1 1
50 383100777 2 1
51 383100777 3 1
52 383100777 4 1
53 383100777 5 1
54 383100777 6 1
55 383100777 7 1
56 383100777 8 1
我可以看到您指定的条件与显示的输出之间存在一些矛盾。你能再查一下吗?如果我遗漏了什么,请告诉我。很抱歉造成混乱。我已经对打字错误进行了更改。如果是序列1,0,1,请说明是应该更改为1,1,1还是1,0,0?应该更改为1,1,1。只剩下10个观察结果?非常感谢!我认为你的答案很有用!你能在这里解释一下求和函数的用途吗?我真的不太明白。谢谢,是的。我只是想学习,所以希望你能澄清你的代码的含义。谢谢。我已经编辑了我的答案和解释!请看。我使用了简单的逻辑,0
当添加到某个值时,返回相同的值。将每列的此值与该列中的最后一个值进行检查,以确保它是该组中的最后一个0
。最后一次0
之后,它被更改为0
,其他所有内容都被更改为1
。这是否澄清了你的疑虑?
library(tidyverse)
df_repaired <- df %>% group_by(id) %>%
mutate(dummy_id = row_number(),
col1 = last(which(node ==1)),
node2 = ifelse(dummy_id > col1 | is.na(col1), 0, 1)) %>%
ungroup() %>%
select(-node, -dummy_id, -col1) %>%
rename(node = node2)
> print(df_repaired, n=56)
# A tibble: 56 x 3
id year node
<dbl> <dbl> <dbl>
1 383100111 1 1
2 383100111 2 1
3 383100111 3 1
4 383100111 4 1
5 383100111 5 1
6 383100111 6 1
7 383100111 7 1
8 383100111 8 0
9 383100222 1 1
10 383100222 2 1
11 383100222 3 1
12 383100222 4 1
13 383100222 5 1
14 383100222 6 1
15 383100222 7 1
16 383100222 8 1
17 383100333 1 1
18 383100333 2 1
19 383100333 3 1
20 383100333 4 1
21 383100333 5 1
22 383100333 6 1
23 383100333 7 1
24 383100333 8 1
25 383100444 1 1
26 383100444 2 1
27 383100444 3 1
28 383100444 4 1
29 383100444 5 1
30 383100444 6 1
31 383100444 7 1
32 383100444 8 0
33 383100555 1 1
34 383100555 2 1
35 383100555 3 1
36 383100555 4 1
37 383100555 5 1
38 383100555 6 1
39 383100555 7 1
40 383100555 8 1
41 383100666 1 0
42 383100666 2 0
43 383100666 3 0
44 383100666 4 0
45 383100666 5 0
46 383100666 6 0
47 383100666 7 0
48 383100666 8 0
49 383100777 1 1
50 383100777 2 1
51 383100777 3 1
52 383100777 4 1
53 383100777 5 1
54 383100777 6 1
55 383100777 7 1
56 383100777 8 1