我有一个数据框如下:
df<-read.table(text="ID RE AL
140343 TC T
200012 A G
457096 GAA GAAA
555084 AG A
557151 T TAA
752311 GAATTAAT GAAT
810001 ATTTTT ATTTT
880420 GAAAAAAAAA GAAAAAAAAAA", header=TRUE, colClasses="character")
我想将字母“RE”或“AL”中的较长字符串替换为字母“I”,将较短的字符串替换为字母“D”。如果两列都有一个字母,则没有变化。
预期结果:
ID RE AL
140343 I D
200012 A G
457096 D I
555084 I D
557151 D I
752311 I D
810001 I D
880420 D I
我尝试了我的脚本:
max <- apply(df[2:3], 1, function(x) max(nchar(x)))
index <- max > 1
if(nchar(df$RE[index])==max[index]){
df$RE[index] <- "I"
df$AL[index] <- "D"
}else{
df$RE[index] <- "D"
df$AL[index] <- "I"
}
答案 0 :(得分:4)
碱基R向量化溶液。第一行定义要处理的行的子集。然后两条具有相反方向的线进行比较,您可以根据比较选择“D”或“I”:
noneq <- with( df, (nchar(RE) != 1)|( nchar(AL) != 1) )
df[ noneq, "RE"] <- with(df[ noneq, ], c("D","I")[1+(nchar(RE) > nchar(AL) )])
df[ noneq, "AL"] <- with(df[ noneq, ], c("D","I")[1+(RE=="D" )]) # opposite of RE
df
#==============
ID RE AL
1 140343 I D
2 200012 A G
3 457096 D I
4 555084 I D
5 557151 D I
6 752311 I D
7 810001 I D
8 880420 D I
答案 1 :(得分:2)
这是一个可能适合您的dplyr
解决方案
library(dplyr)
df %>%
mutate(RE = ifelse(nchar(RE) != 1 | nchar(AL) != 1,
ifelse(nchar(RE) > nchar(AL), 'I', 'D'), RE),
AL = ifelse(RE=='I', 'D', ifelse(RE=='D', 'I', AL)))
## ID RE AL
## 1 140343 I D
## 2 200012 A G
## 3 457096 D I
## 4 555084 I D
## 5 557151 D I
## 6 752311 I D
## 7 810001 I D
## 8 880420 D I
答案 2 :(得分:0)
这是一个简单的for循环,可以完成工作:
for (i in seq(1:nrow(df))){
if(nchar(df[i, 3]) - nchar(df[i, 2]) < 0){
df[i, 3] <- "D"
df[i, 2] <- "I"
}else if(nchar(df[i, 3]) - nchar(df[i, 2]) > 0){
df[i, 3] <- "I"
df[i, 2] <- "D"
}
}
答案 3 :(得分:0)
另一种基本R解决方案(与@ 42-答案相比,但预先定义了索引):
> df
ID RE AL
1 140343 I D
2 200012 A G
3 457096 D I
4 555084 I D
5 557151 D I
6 752311 I D
7 810001 I D
8 880420 D I
给出:
{{1}}