我想编辑如下文件。
文件结构,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",但是如果值已经出现在列表中怎么编辑?
我很感激每一个提示,提前谢谢!
答案 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