基于与向量的重叠替换数据框的列中的值

时间:2015-06-01 19:12:13

标签: r for-loop replace

晚上好,

我有一个150.000行和7列的大型数据框如下

     ID cola colb colc cold cole colf
 XXXYYY    0    0    0    0    0    0
 XXYYXX    0    0    0    0    0    0
 XYXYXY    0    0    0    0    0    0
 YYYXXX    0    0    0    0    0    0
...

我还有矢量veca,vecb,vecc,vecd,vece和vecf,其中包含我的数据帧中ID的子集。 我想写一个循环,我根据数据帧和向量之间的ID号重叠为列分配1。 例如,如果veca <- c("XXXYYY", "XXYYXX")则输出应为:

     ID cola colb colc cold cole colf
 XXXYYY    1    0    0    0    0    0
 XXYYXX    1    0    0    0    0    0
 XYXYXY    0    0    0    0    0    0
 YYYXXX    0    0    0    0    0    0
...

...我想重复所有专栏。

通常我会写这样的东西:

dataframe$cola[dataframe$ID %in% veca ] <- 1

然而,我在循环中编写上述内容时遇到了麻烦。我尝试了各种粘贴和分配的组合,但到目前为止还没有运气。

稍后在我的代码中我还想根据ID号的类似重叠删除数据帧的行(通常写成dataframe <- dataframe[!(dataframe$ID %in% veca),])但我认为这与

非常相似

最后,我应该补充一点,我的平台是x86_64-w64-mingw32,我的R版本是R版本3.1.2

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:2)

您可以使用row/column索引

lst <- mget(paste0('vec', letters[1:6]))
d2 <- stack(lst)
d1[-1][cbind(match(d2$values, d1$ID),
   match(substr(d2$ind, 4,4), substr(names(d1)[-1], 4,4)))] <- 1
d1
#      ID cola colb colc cold cole colf
#1 XXXYYY    1    0    1    0    1    1
#2 XXYYXX    1    0    0    0    0    0
#3 XYXYXY    0    1    0    1    0    1
#4 YYYXXX    0    0    1    0    0    0

要删除重叠的ID,

IDstoremove <- Reduce(`intersect`, lst) #in this example, none
d1[!(d1$ID %in% IDstoremove),]

数据

d1 <- structure(list(ID = c("XXXYYY", "XXYYXX", "XYXYXY", "YYYXXX"), 
cola = c(0L, 0L, 0L, 0L), colb = c(0L, 0L, 0L, 0L), colc = c(0L, 
0L, 0L, 0L), cold = c(0L, 0L, 0L, 0L), cole = c(0L, 0L, 0L, 
0L), colf = c(0L, 0L, 0L, 0L)), .Names = c("ID", "cola", 
"colb", "colc", "cold", "cole", "colf"), class = "data.frame", 
row.names = c(NA, -4L))

veca<-c("XXXYYY","XXYYXX")
vecb <- 'XYXYXY'
vecc <- c('XXXYYY', 'YYYXXX')
vecd <- 'XYXYXY'
vece <- 'XXXYYY'
vecf <- c('XXXYYY', 'XYXYXY')

答案 1 :(得分:1)

你能发布为什么它不起作用吗?您建议的代码为我生成正确的输出:

    > ## Set up the dataframe d1
    > z4<-rep(0,4) # 4 zeros
    > d1<-data.frame(ID=c("XXXYYY","XXYYXX","XYXYXY","YYYXXX"), cola=z4,colb=z4,colc=z4,cold=z4,cole=z4,colf=z4)
    > veca<-c("XXXYYY","XXYYXX")
    > d1
          ID cola colb colc cold cole colf
    1 XXXYYY    0    0    0    0    0    0
    2 XXYYXX    0    0    0    0    0    0
    3 XYXYXY    0    0    0    0    0    0
    4 YYYXXX    0    0    0    0    0    0

    > ## change cola
    > d1$cola[d1$ID %in% veca ] <- 1
    > d1
          ID cola colb colc cold cole colf
    1 XXXYYY    1    0    0    0    0    0
    2 XXYYXX    1    0    0    0    0    0
    3 XYXYXY    0    0    0    0    0    0
    4 YYYXXX    0    0    0    0    0    0

    > ## Remove lines
    > d1<-d1[!(d1$ID %in% veca),]
    > d1
          ID cola colb colc cold cole colf
    3 XYXYXY    0    0    0    0    0    0
    4 YYYXXX    0    0    0    0    0    0

答案 2 :(得分:1)

#addones

lstcol <- list('cola', 'colb')
lstvec <- list(veca, vecb)

myfunc <- function(COL, VEC) {
  dataframe[[COL]][dataframe$ID %in% VEC] <<- 1
}

for(i in 1:length(lstcol)) {
  myfunc(lstcol[[i]], lstvec[[i]])
}

dataframe

#      ID cola colb colc cold cole colf
#1 XXXYYY    1    0    0    0    0    0
#2 XXYYXX    1    0    0    0    0    0
#3 XYXYXY    0    1    0    0    0    0
#4 YYYXXX    0    0    0    0    0    0

#remove lines

rowstoremove <- c('YYYXXX')
dataframe[!dataframe$ID == rowstoremove, ]

#       ID cola colb colc cold cole colf
# 1 XXXYYY    1    0    0    0    0    0
# 2 XXYYXX    1    0    0    0    0    0
# 3 XYXYXY    0    1    0    0    0    0

您可以填写完整的veccol列表来完成输出。