用数字顺序替换文件之间的匹配

时间:2018-10-17 16:46:20

标签: r bash loops

我有两个文本文件:

FileA具有三列:

Col1 Col2 Col3  
111111 111111 0  
222222 222222 0  
333333 333333 0  
444444 444444 0  
666666 666666 0

FileB有一列(无标题):

222222  
444444  
555555  
666666

如果与FileB中的内容匹配,我想替换FileA的第1列和第2列中的内容。我希望替换是从-4开始的负数序列。

所需的输出:

Col1 Col2 Col3  
111111 111111 0  
-4 -4 0  
333333 333333 0  
-5 -5 0  
-6 -6 0

FileA的实际长度约为500k,FileB的实际长度为80。

R或bash解决方案将不胜感激。

3 个答案:

答案 0 :(得分:1)

使用基数R,您可以这样做。

FileA[] <- lapply(FileA, function(x){
  i <- match(FileB$Col1, x)
  if(all(!is.na(i))) x[i] <- -seq_along(i) - 3
  x
})

FileA
#    Col1   Col2 Col3
#1 111111 111111    0
#2     -4     -4    0
#3 333333 333333    0
#4     -5     -5    0
#5     -6     -6    0
#6     -7     -7    0

数据。

FileA <- data.frame(Col1 = c(111111, 22222, 333333, 444444, 555555, 666666),
                    Col2 = c(111111, 22222, 333333, 444444, 555555, 666666),
                    Col3 = 0)
FileB <- data.frame(Col1 = c(22222, 444444, 555555, 666666))

答案 1 :(得分:0)

这可以解决嵌套循环的问题:

equalities <- apply(filea, 2, function(x) x %in% fileb)
result <- filea
replacement <- c(-4:-99)

for( i in 1:ncol(result)) {
  result[,i] <- ifelse(equalities[,i], "toreplace", result[,i])
  nbmatches <- 1
  for( j in 1:nrow(result)) {
    if("toreplace"==result[j,i]) nbmatches <- nbmatches + 1
    result[j,i] <- ifelse("toreplace"==result[j,i], replacement[nbmatches],result[j,i])
  }

  }
result
    Col1   Col2 Col3
1 111111 111111    0
2     -5     -5    0
3 333333 333333    0
4     -6     -6    0
5     -7     -7    0

答案 2 :(得分:0)

这假设两列的值相同

(\d+)([<=>]{1,2})(\d+)

说明 将第一个文件值保存在数组$ awk -v c=-4 'NR==FNR {a[$1]; next} $1 in a {$1=$2=c--}1' fileB fileA Col1 Col2 Col3 111111 111111 0 -4 -4 0 333333 333333 0 -5 -5 0 -6 -6 0 中。如果fileB的第一个字段在数组a中,请用计数器a替换第一和第二个字段,并减少该计数器。打印所有行(是否更新)。