输入:
df<-data.frame(df<-data.frame(ID=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17),
P=c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3),
G=c(0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0),
NPO=c(1,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,NA,1,NA,NA,1,NA),
PO=c(1,1,1,1,1,2,2,2,2,0,0,0,1,1,1,1,1),
T=c(0,1,2,NA,NA,1,2,3,5,NA,NA,NA,1,2,4,0,1))
我想生成一个新列“ C”,该列以“ 1”指示“ T”列中的非“ NA”单元格具有与“ G”列中的“ 1”相对应的端点,并且起点以“ NPO”列中的“ 1”开头。
“ PO”和“ P”列可用于帮助指示是否有新数据段要检查?在任何给定的“ P”值运行中,新列“ C”中将永远只运行一次“ 1”,并且最多与“ PO”中的运行次数一样长。每当“ NPO”中的值为“ 1”或在“ G”中的值为“ 1”之后,PO值都会重置。 “ P”随着“ G”中的每“ 1”而增加。
我尝试了一些ifelse语句,但是不知道如何指示与同一行不同的行,或者如何在不参考我要创建的列的情况下这样做。
输出:
df<-data.frame(ID=c(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17),
P=c(1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,3,3),
G=c(0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0),
NPO=c(1,NA,NA,NA,NA,1,NA,NA,NA,NA,NA,NA,1,NA,NA,1,NA),
PO=c(1,1,1,1,1,2,2,2,2,0,0,0,1,1,1,1,1),
T=c(0,1,2,NA,NA,1,2,3,5,NA,NA,NA,1,2,4,0,1),
C=c(0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,0,0))
ID P G NPO PO T C
1 1 0 1 1 0 0
2 1 0 NA 1 1 0
3 1 0 NA 1 2 0
4 1 0 NA 1 NA 0
5 1 0 NA 1 NA 0
6 1 0 1 2 1 1
7 1 0 NA 2 2 1
8 1 0 NA 2 3 1
9 1 1 NA 2 5 1
10 2 0 NA 0 NA 0
11 2 0 NA 0 NA 0
12 2 0 NA 0 NA 0
13 2 0 1 1 1 1
14 2 0 NA 1 2 1
15 2 1 NA 1 4 1
16 3 0 1 1 0 0
17 3 0 0 1 1 0
答案 0 :(得分:1)
使用fill
中的tidyr
函数。这完全基于将T
中向上连续的非缺失值填充为1,并将0放置在其他位置。
我根本不使用P
,NPO
或PO
列。如果那没有道理,您可能需要详细说明。
df$result = ifelse(is.na(df$T), 0, NA)
df$result[df$G == 1] = 1
df = tidyr::fill(df, result, .direction = "up")
df$result[is.na(df$result)] = 0
df
all(df$C == df$result)
# [1] TRUE
答案 1 :(得分:1)
以下是使用dplyr
的方法:
library(dplyr)
df %>%
group_by(P, PO) %>%
mutate(C = +(first(NPO == 1) & last(G == 1)))
# A tibble: 17 x 7
# Groups: P, PO [5]
ID P G NPO PO T C
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int>
1 1 1 0 1 1 0 0
2 2 1 0 NA 1 1 0
3 3 1 0 NA 1 2 0
4 4 1 0 NA 1 NA 0
5 5 1 0 NA 1 NA 0
6 6 1 0 1 2 1 1
7 7 1 0 NA 2 2 1
8 8 1 0 NA 2 3 1
9 9 1 1 NA 2 5 1
10 10 2 0 NA 0 NA 0
11 11 2 0 NA 0 NA 0
12 12 2 0 NA 0 NA 0
13 13 2 0 1 1 1 1
14 14 2 0 NA 1 2 1
15 15 2 1 NA 1 4 1
16 16 3 0 1 1 0 0
17 17 3 0 NA 1 1 0