我正在运行以下代码:
data<-cbind(c(rep(1,2),rep(2,4),rep(3,4)),c(rep(1:3,3),1),c("A",
"B","A",rep("B",2),"A","A","B","A","A"))
data<-data.frame(data)
colnames(data)<-c("sub","days","cat") ## Changing col names
work<-NULL
for(i in 1:length(data$sub)) {
sand<-subset(data,sub==i)
for (j in 1:length(sand$cat)) {
ifelse(sand$cat[j]=="B",sand$cat[j+1]=="B","A")
}
work<-rbind(work,sand)
}
> work
sub days cat
1 1 1 A
2 1 2 B
3 2 3 A
4 2 1 B
5 2 2 B
6 2 3 A
7 3 1 A
8 3 2 B
9 3 3 A
10 3 1 A
不是我想要的东西。当我运行ifelse部分时,我想要的是它接触B的那一刻,子集的剩余值也返回B.第6,9和10行应该给我B代替A(因为在sub == 2下,cat ==“B”在第5行,所以我应该得到cat =“B”在第6行,因为它仍然是sub = 2 )。
希望你理解这个问题。在此先感谢您的帮助。
答案 0 :(得分:6)
使用您的示例数据,我可能会运行
cat2<-with(data, levels(cat)[ave(as.numeric(cat), sub, FUN=cummax)])
会给出
cbind(data, cat2)
# sub days cat cat2
# 1 1 1 A A
# 2 1 2 B B
# 3 2 3 A A
# 4 2 1 B B
# 5 2 2 B B
# 6 2 3 A B
# 7 3 1 A A
# 8 3 2 B B
# 9 3 3 A B
# 10 3 1 A B
我使用ave
在由sub
定义的群组中工作,然后我使用cummax
找到每个点在每个点看到的最高因子水平(当它是时,它将是B看到)。我不得不做一些鬼混,因为cummax
只适用于数字向量。
答案 1 :(得分:1)
我想我理解你想要的东西......对你的代码进行一些小改动应该可以解决问题: 1)只能达到唯一的&#39; sub&#39;值(第6行 - &#39; i&#39;循环):您不需要遍历表格中的每一行;只有&#39; sub&#39;的唯一值 2)只做到倒数第二只“猫”。子集中的行(第8行 - &#39; j&#39;循环):您希望根据先前的值更改下一个值,因此可以在倒数第二行停止 3)不要将下一行值更改为“A&#39; A&#39;如果它不是&#39; B&#39; (第9行):这是根本问题。如果您将下一个值更改为&#39; A&#39;然后下一个循环会将其视为“A&#39;即使它是一个&#39; B&#39;
完整的代码是:
data<-cbind(c(rep(1,2),rep(2,4),rep(3,4)),c(rep(1:3,3),1),c("A",
"B","A",rep("B",2),"A","A","B","A","A"))
data<-data.frame(data)
colnames(data)<-c("sub","days","cat") ## Changing col names
work<-NULL
for(i in 1:length(unique(data$sub))) {
sand<-subset(data,sub==i)
for (j in 1:(length(sand$cat)-1)) {
if(sand$cat[j]=="B")
sand$cat[j+1] = "B"
}
work<-rbind(work,sand)
}
>work
sub days cat
1 1 1 A
2 1 2 B
3 2 3 A
4 2 1 B
5 2 2 B
6 2 3 B
7 3 1 A
8 3 2 B
9 3 3 B
10 3 1 B
这是否符合您的要求?