仅根据匹配

时间:2015-06-10 12:50:26

标签: r match lapply

我正在尝试根据匹配更新popsnp内更高范围内的变量(lapply)。我无法弄清楚更新值的语法,我目前用NA覆盖任何以前存在的值:

lapply(1:22, function(i){
  in.name<-paste("/data/mdp14aps/ld/chr", i, ".ld", sep="")
  out.name<-paste("/data/mdp14aps/R/ldatachr", i, ".rda", sep="")
  ldata<-read.csv(in.name, sep="", header=TRUE,
                  colClasses=c(NA,NA,NA,NA,NA,NA,"NULL"))
  freq<-count(ldata, c("SNP_A", "CHR_A", "BP_A"))

  #the part I'm not sure about
  popsnp$chrom<<-freq[match(popsnp$marker, freq$SNP_A),2]
  popsnp$position<<-freq[match(popsnp$marker, freq$SNP_A),3]
  popsnp$freq<<-freq[match(popsnp$marker, freq$SNP_A),4]

  save(ldata,file=out.name)
  rm(ldata, freq)
})

我想保留我在lapply的迭代之间设置的值,因此我最终得到的popsnp包含chrom的{​​em>所有值,{{ 1}}和position,而不仅仅是最后一次迭代。

我觉得这应该是直截了当的,但我仍然对R不熟悉。

玩具示例:

freq

我希望test<-data.frame(A = c("a", "b", "c", "d", "e"), B = c(rep(NA,5))) test1<-data.frame(A = c("a", "b"), B = c(1, 2)) test2<-data.frame(A = c("c", "d", "e"), B = c(3, 4, 5)) test$B<-test1[match(test$A, test1$A), 2] test$B<-test2[match(test$A, test2$A), 2] 的值为1-5。

1 个答案:

答案 0 :(得分:0)

您的玩具示例的更新

您需要对作业的两侧进行子集化,并将条件转换为逻辑子集向量。

logical1 <- !is.na(test1[match(test$A, test1$A),2]) # TRUE/FALSE
logical2 <- !is.na(test1[match(test$A, test2$A),2])

test[t1,] <- test1[t1,] # selects only TRUE rows
test[t2,] <- test2[t2,] 

我建议您单独查看每个元素,以便了解发生了什么。

此前...

我不完全确定我理解你的例子正在努力实现的目标。因此,我将为您提供子集化的玩具示例:

dat <- data.frame(
 A = sample(letters[3:26],26,replace = TRUE)
 B = runif(26)
)

# Replaces everything in column B where column A == "a"
dat[dat$a == "c", "B"] <- 1

# dat$A == "c" returns a TRUE/FALSE vector, "B" returns column "B".

最佳做法是在子集化时始终使用TRUE / FALSE条件以避免将来出现错误。您可以按行号进行子集,但它总是会变得混乱。

值得注意的是,您使用<<-会将您对变量的更改推送到您的函数范围之外的父环境。这可能会在将来导致意想不到的结果。最好提供您想要更改的变量,然后在操作函数结束时再次返回它。这样你就有了明确的事件序列。

myfun <- function(x,y) { 
  # ... do stuff to y
  return(y)
}

y <- myfun(x,y) 

最终更新

最后,关于删除不必要的列。典型的做法是在按名称(最佳实践)或参考编号导入后删除它们(数据的更改打破了这一点)。

ldata[c('col1','col2',...)] <- NULL # drop