我有两个长度不等的向量。我试图首先填充变量,无论字符串是否在两个给定的向量中匹配,还尝试从一个向量中取值来填充结果向量的值。
数据如下:
a<-data.frame(cbind(c("Ab", "Ng", "Dc"), c(1, 0, 1)))
b<-data.frame(cbind(c("Ab", "Ng", "Rt", "Dc", "Ty"), c(rep(NA, 5))))
第一个向量是较大向量(b)的子集,并且这些向量应在向量之间匹配。我想在较大的向量(b)中设置一个指标变量。想象一下以下场景:所有字符串代表一个班级的学生。与向量a相关联的指示符指示种族,但向量a中的所有名称都是女性。第二个向量(b)代表班上的所有学生。最终结果:“Ab”和“Ng”的值为1,其他所有学生的则为0。
我的循环脚本目前是:
for(i in 1:nrow(b)){
for(j in 1:nrow(a)){
if(as.character(b[,1][i]) %in% a[,1] & a[,2][j]==1){b[,2][i]==1}
else{b[,2][i]<-0}
}
}
产生以下结果:
structure(list(X1 = structure(c(1L, 3L, 4L, 2L, 5L), .Label = c("Ab",
"Dc", "Ng", "Rt", "Ty"), class = "factor"), X2 = c(0, 0, 0, 0,
0)), .Names = c("X1", "X2"), row.names = c(NA, -5L), class = "data.frame")
期望的结果应该是:
structure(list(X1 = structure(c(1L, 3L, 4L, 2L, 5L), .Label = c("Ab", "Dc", "Ng", "Rt", "Ty"), class = "factor"), X2 = c(1, 0, 0, 1, 0)), .Names = c("X1", "X2"), row.names = c(NA, -5L), class = "data.frame")
我的问题是: 为什么结果与原始输入不匹配?我怎样才能让这个循环正确执行我想要的过程,这样我才能得到理想的结果?
答案 0 :(得分:1)
你在寻找下面的吗?基于我对叙述的最好理解的尝试。
a<-data.frame(cbind(c("Ab", "Ng", "Dc"), c(1, 0, 1)))
b1<-data.frame(X1 = c("Ab", "Ng", "Rt", "Dc", "Ty"))
library(data.table)
setDT(a); setDT(b1)
setkey(a, X1)
out = a[b1]
out[is.na(out)] = 0
out
X1 X2
1: Ab 1
2: Ng 0
3: Rt 0
4: Dc 1
5: Ty 0
答案 1 :(得分:1)
我想你需要a
中b
的简单左连接。使用dplyr包的替代方法:
library(dplyr)
df <- b %>%
left_join(a, by="X1") %>%
mutate(X2 = ifelse(is.na(X2.y), 0, X2.y %>% as.character %>% as.numeric)) %>%
select(X1, X2)
结果:
> df
X1 X2
1 Ab 1
2 Ng 0
3 Rt 0
4 Dc 1
5 Ty 0
我使用了您的示例data.frames,但我不知道您的实际data.frames是如何设置的。但请注意列类型。我必须使用as.character
后跟as.numeric
才能正确行事。似乎“因素”不是你所需要的。
问候!
答案 2 :(得分:0)
最好使用像%in%
这样的矢量化函数,假设我理解了所需的结果:
> b$X2 <- as.numeric( b$X1 %in% a$X1 )
> b
X1 X2
1 Ab 1
2 Ng 1
3 Rt 0
4 Dc 1
5 Ty 0
一般来说,使用data.frame(cbind...))
形式是一个非常糟糕的主意,因为您始终会将所有列的模式强制转换为单一模式。
答案 3 :(得分:0)
以下可能会有所帮助:
> cc = rbind(a[a$X2==1,], b)
> cc[!duplicated(cc$X1),]
X1 X2
1 Ab 1
3 Dc 1
4 Ng <NA>
5 Rt <NA>
7 Ty <NA>