我想通过将“X”或“Y”列中的文本相应地匹配为“x”或“y”来替换由“/”分隔的元素,而忽略“ - ”。
df <- data.frame("X"=c("A","AB","CD","E","T"),
"Y"=c("AT","A","CDCD","F","A"),
"R1"=c("A/A","AB/AB","CD/CD","E/E","-/-"),
"R2"=c("A/AT","AB/AB","CD/CDCD","F/F","T/T"),
"R3"=c("AT/AT","A/AB","CDCD/CDCD","E/F","A/T"),
"R4"=c("AT/A","A/A","-/-","F/E","T/A"),
"R5"=c("-/-","A/AB","CDCD/CD","F/F","A/A"),
"R6"=c("A/A","-/-","CD/CD","E/E","-/-"))
预期结果是:
X Y R1 R2 R3 R4 R5 R6
A AT x/x x/y y/y y/x -/- x/x
AB A x/x x/x y/x y/y y/x -/-
CD CDCD x/x x/y y/y -/- y/x x/x
E F x/x y/y x/y y/x y/y x/x
T A -/- x/x y/x x/y y/y -/-
我不知道如何以有效的方式做到这一点。我感谢任何帮助。
答案 0 :(得分:2)
非常棘手的问题!这是一个解决方案:
df[,3:ncol(df)] <- t(apply(df,1,function(R) sapply(strsplit(R[3:ncol(df)],'/'),function(S) paste0(gsub(paste0('^',R[1],'$'),'x',gsub(paste0('^',R[2],'$'),'y',S)),collapse='/'))));
df;
## X Y R1 R2 R3 R4 R5 R6
## 1 A AT x/x x/y y/y y/x -/- x/x
## 2 AB A x/x x/x y/x y/y y/x -/-
## 3 CD CDCD x/x x/y y/y -/- y/x x/x
## 4 E F x/x y/y x/y y/x y/y x/x
## 5 T A -/- x/x y/x x/y y/y -/-
答案 1 :(得分:1)
这是 dplyr 和 stringr 的一种方式。
library(dplyr)
library(stringr)
df[] <- lapply(df, as.character)
df %>%
rowwise() %>%
do({
vars <- c(.$X, .$Y)
# ordering gives precedence to longer vars
replacements <- setNames(c('x', 'y'), vars)[order(nchar(vars), decreasing=TRUE)]
setNames(data.frame(.[1:2], as.list(str_replace_all(unlist(tail(., -2)), replacements))), names(.))
})
# X Y R1 R2 R3 R4 R5 R6
# 1 A AT x/x x/y y/y y/x -/- x/x
# 2 AB A x/x x/x y/x y/y y/x -/-
# 3 CD CDCD x/x x/y y/y -/- y/x x/x
# 4 E F x/x y/y x/y y/x y/y x/x
# 5 T A -/- x/x y/x x/y y/y -/-