我的数据框看起来像这样:
UIView
我想编写一个能够查看每个' b'列并询问它是否包含值' HP'。如果是,那么其他六个' b'列包含' CP'或者' KP',我想改变价值' HP'进入' CP'或者' KP'取决于哪个是多数。如果CP占多数,请将HP更改为CP。如果KP占多数,则将HP更改为KP。
(请注意,b1和b2,b3和b4等的值总是相同的,所以实际上只需要查看4列,b1,b3,b5和b7)。
澄清一下,如果列是例如HP HP CP CP CP CP KP KP,我想将两个HP更改为CP(并使其他列保持不变)。
所以,我给出的例子将成为:
chr <- c(1,1,1,1,1)
b1 <- c('HP', 'HP', 'CP', 'CP', 'KP')
b2 <- c('HP', 'HP', 'CP', 'CP', 'KP')
b3 <- c('CP', 'KP', 'CP', 'HP', 'CP')
b4 <- c('CP', 'KP', 'CP', 'HP', 'CP')
b5 <- c('CP', 'CP', 'KP', 'KP', 'HP')
b6 <- c('CP', 'CP', 'KP', 'KP', 'HP')
b7 <- c('CP', 'KP', 'HP', 'CP', 'CP')
b8 <- c('CP', 'KP', 'HP', 'CP', 'CP')
df <- data.frame(chr, b1,b2,b3,b4,b5,b6,b7,b8)
我用if语句编写了一个函数(仅用于df $ b1),但它不起作用。 (请注意HP更改为KP或CP的规则取决于有多少其他CP或KP):
chr <- c(1,1,1,1,1)
b1 <- c('CP', 'KP', 'CP', 'CP', 'KP')
b2 <- c('CP', 'KP', 'CP', 'CP', 'KP')
b3 <- c('CP', 'KP', 'CP', 'CP', 'CP')
b4 <- c('CP', 'KP', 'CP', 'CP', 'CP')
b5 <- c('CP', 'CP', 'KP', 'KP', 'CP')
b6 <- c('CP', 'CP', 'KP', 'KP', 'CP')
b7 <- c('CP', 'KP', 'CP', 'CP', 'CP')
b8 <- c('CP', 'KP', 'CP', 'CP', 'CP')
df <- data.frame(chr, b1,b2,b3,b4,b5,b6,b7,b8)
df
非常感谢您的帮助。我真的坚持这个。
编辑:这是我的实际数据样本,它比我上面给出的例子更复杂。
fun <- function(df){
if(df$b1 == 'HP' && df$b3 == 'CP' && df$b5 == 'CP' && df$b7 == 'CP') {df$b1 <- 'KP'}
if(df$b1 == 'HP' && df$b3 == 'KP' && df$b5 == 'CP' && df$b7 == 'CP') {df$b1 <- 'CP'}
if(df$b1 == 'HP' && df$b3 == 'CP' && df$b5 == 'KP' && df$b7 == 'CP') {df$b1 <- 'CP'}
if(df$b1 == 'HP' && df$b3 == 'CP' && df$b5 == 'CP' && df$b7 == 'KP') {df$b1 <- 'CP'}
if(df$b1 == 'HP' && df$b3 == 'KP' && df$b5 == 'KP' && df$b7 == 'CP') {df$b1 <- 'KP'}
if(df$b1 == 'HP' && df$b3 == 'KP' && df$b5 == 'CP' && df$b7 == 'KP') {df$b1 <- 'KP'}
if(df$b1 == 'HP' && df$b3 == 'CP' && df$b5 == 'KP' && df$b7 == 'KP') {df$b1 <- 'KP'}
if(df$b1 == 'HP' && df$b3 == 'KP' && df$b5 == 'KP' && df$b7 == 'KP') {df$b1 <- 'CP'}
df$b2 <-df$b1
}
答案 0 :(得分:3)
您可以尝试:
t(apply(df[,-1], 1, function(rg){
occ_rg <- table(rg)
rg[grep("HP",rg)] <- names(occ_rg)[which.max(occ_rg)]
return(rg)}))
所以,拥有你的新df:
df <- data.frame(chr=df[, 1], t(apply(df[,-1], 1, function(rg){
occ_rg <- table(rg)
rg[grep("HP",rg)] <- names(occ_rg)[which.max(occ_rg)]
return(rg)})),
stringsAsFactors=F)
# chr b1 b2 b3 b4 b5 b6 b7 b8
#1 1 CP CP CP CP CP CP CP CP
#2 1 KP KP KP KP CP CP KP KP
#3 1 CP CP CP CP KP KP CP CP
#4 1 CP CP CP CP KP KP CP CP
#5 1 KP KP CP CP CP CP CP CP
编辑
如果您有其他列,而您想要更改的列是唯一以“b”开头的列,您可以执行以下操作:
df[, grepl("^b", colnames(df))] <- t(apply(df[, grepl("^b", colnames(df))],
1,
function(rg){
occ_rg <- table(rg)
rg[grep("HP",rg)] <- names(occ_rg)[which.max(occ_rg)]
return(rg)}))
<强> 实施例 强>
有了这个df:
# chr c1 b1 b2 b3 b4 b5 b6 b7 b8 c2
#1 1 1 HP HP CP CP CP CP CP CP 11
#2 1 2 HP HP KP KP CP CP KP KP 12
#3 1 3 CP CP CP CP KP KP HP HP 13
#4 1 4 CP CP HP HP KP KP CP CP 14
#5 1 5 KP KP CP CP HP HP CP CP 15
你得到:
# chr c1 b1 b2 b3 b4 b5 b6 b7 b8 c2
#1 1 1 CP CP CP CP CP CP CP CP 11
#2 1 2 KP KP KP KP CP CP KP KP 12
#3 1 3 CP CP CP CP KP KP CP CP 13
#4 1 4 CP CP CP CP KP KP CP CP 14
#5 1 5 KP KP CP CP CP CP CP CP 15
编辑2
如果您有其他值而不是“HP”,“CP”和“KP”,并希望用“CP”或“KP”替换“HP”,具体取决于发生的最多,您可以这样做:
df[, grepl("^b", colnames(df))] <- t(apply(df[, grepl("^b", colnames(df))],
1,
function(rg){
occ_rg <- table(rg)
occ_rg <- occ_rg[grepl("KP|CP", names(occ_rg))]
rg[grep("HP",rg)] <- names(occ_rg)[which.max(occ_rg)]
return(rg)}))
说明(对于edit2):
df[, grepl("^b", colnames(df))] <- # only the columns beginning with b are considered (so the other ones will remain untouched)
t( # the results of apply will be transposed
apply(df[, grepl("^b", colnames(df))], # apply on df with only the columns beginning by b
1, # by row
function(rg){ # a function that takes a vector "rg" as input
occ_rg <- table(rg) # computes the table
occ_rg <- occ_rg[grepl("KP|CP", names(occ_rg))] # keep only the occurrences of either "KP" or "CP"
rg[grep("HP",rg)] <- names(occ_rg)[which.max(occ_rg)] # replace in the vector rg the "HP" elements by "KP" or "CP" depending on which occurs the most
return(rg) # finally returns the vector rg
}))