使用awk或R编辑文件,如果重复则更改值

时间:2016-08-31 14:32:34

标签: r bash awk

我想编辑如下文件。

文件结构,3列

 1. 1 xy1 0
 2. 1 xy2 0
 3. 1 xy3 0.04
 4. 1 xy4 0.05
 5. 1 xy5 0.33
 6. 1 xy6 0.33
 7. 1 xy7 0.33

如果第3列中的特定值出现两次甚至几次(例如" 0"第1行和第2行," 0.33"第5,6和7行)我想编辑重复的值。每次出现一个值我都希望将重复值增加0.001。它看起来像这样:

 1. 1 xy1 0
 2. 1 xy2 0.001
 3. 1 xy3 0.04
 4. 1 xy4 0.05
 5. 1 xy5 0.33
 6. 1 xy6 0.331
 7. 1 xy7 0.332

第2,6和7行的值增加了0.001。

如何使用awk / bash或R? 我可以使用" cut -f 3 file |来识别重复项排序| uniq -d",但是如果值已经出现在列表中怎么编辑?

我很感激每一个提示,提前谢谢!

4 个答案:

答案 0 :(得分:6)

$ awk '{$3+=(c[$3]++/1000)}1' file
1 xy1 0
1 xy2 0.001
1 xy3 0.04
1 xy4 0.05
1 xy5 0.33
1 xy6 0.331
1 xy7 0.332

答案 1 :(得分:2)

R 中,假设您的数据位于数据框中,例如

d <- read.table(text = "
  1 xy1 0
  1 xy2 0
  1 xy3 0.04
  1 xy4 0.05
  1 xy5 0.33
  1 xy6 0.33
  1 xy7 0.33", header = FALSE)

我们可以使用第3列中的值拆分数据框,然后按顺序添加0.001到每个子集中的值:

d <- do.call(rbind, by(d, d$V3, function(x) {
  x$V3 <- x$V3 + 0.001 * (seq_along(x$V3) - 1)
  x
}))
rownames(d) <- NULL
d
#   V1  V2    V3
# 1  1 xy1 0.000
# 2  1 xy2 0.001
# 3  1 xy3 0.040
# 4  1 xy4 0.050
# 5  1 xy5 0.330
# 6  1 xy6 0.331
# 7  1 xy7 0.332

答案 2 :(得分:0)

awk '{
   if (seen[$3] == "") {
     print $1,$2,$3; seen[$3]=$3
   } else {
     seen[$3] += 0.001; print $1,$2,seen[$3]
   }
}'

注意它可能会占用大量内存,具体取决于输入文件。

答案 3 :(得分:0)

这是一个R解决方案。

假设df是您的数据框,然后使用while您可以获得所需的输出。

> while(any(duplicated(df$V3))){
    ind <- duplicated(df$V3)
    df$V3[ind] <- df$V3[ind] + 0.001
  }
> 
> df
  V1  V2    V3
1  1 xy1 0.000
2  1 xy2 0.001
3  1 xy3 0.040
4  1 xy4 0.050
5  1 xy5 0.330
6  1 xy6 0.331
7  1 xy7 0.332

您的原始df看起来像这样

> df
  V1  V2   V3
1  1 xy1 0.00
2  1 xy2 0.00
3  1 xy3 0.04
4  1 xy4 0.05
5  1 xy5 0.33
6  1 xy6 0.33
7  1 xy7 0.33