使用 If else 检查多个列并根据字符串响应的响应创建一个新列

Using If else to check multiple columns and create a new column based on the response for string responses

我有以下数据集:

hairdf=data.frame(
id=c(1:4),
  typedad=c("straight*","curly"),
  colourdad=c("brown","black"),
  typemom=c("curly","wavy*"),
  colourmom=c("blonde","red"),
  typekid1=c("wavy","mixed*"),
  colourkid1=c("black","blonde"))

我想创建新的列来查看发型,如果头发类型出现在没有星号的“发型”列中则赋值为 1,如果它出现时带有星号则赋值为 2(如果没有出现则为空白)在那一行)。它应该是这样的:

id typedad colourdad typemom colourmom typekid1 colourkid1 straight curly wavy mixed
1 striaght* brown curly blonde wavy black 2 1 1
2 curly black wavy* red mixed* blonde 1 2 2

我的两个问题是,所有其他示例都使用数值,并且所有其他示例都将感兴趣的列彼此相邻放置。我需要看起来与可以位于数据框中任何位置的列中的字符串相匹配的代码。我尝试了以下方法:

straight<- hairdf %>% mutate(across(c("hairtypedad", "hairtypemom", "hairtypekid1"),
                                    ifelse(.=="straight", 1
                                             ifelse(.=="straight*",2, ""
                                             ))))
curly<- hairdf %>% mutate(across(c("hairtypedad", "hairtypemom", "hairtypekid1"),
                                        ifelse(.=="curly", 1
                                                 ifelse(.=="curly*",2, ""
 wavy<- hairdf %>% mutate(across(c("hairtypedad", "hairtypemom", "hairtypekid1"),
                                        ifelse(.=="wavy", 1
                                                 ifelse(.=="wavy*",2, ""
                                                 ))))      
mixed<- hairdf %>% mutate(across(c("hairtypedad", "hairtypemom", "hairtypekid1"),
                                        ifelse(.=="mixed", 1
                                                 ifelse(.=="mixed*",2, ""
                                                 )))) 

但我不确定这段代码是否有意义。此外,这将是乏味的,因为我有更多的发型,所以任何让它更容易的建议也将不胜感激!谢谢!!!

这不是更有效的答案,也不是更通用的解决方案,但可能满足一个解决方案:

#create columns
st <- rep(NA,nrow(hairdf));
cur <- rep(NA,nrow(hairdf));
wav <- rep(NA,nrow(hairdf));
mix <- rep(NA,nrow(hairdf));

#join and define words
hairdf <- cbind(hairdf,st,cur,wav,mix);
words <- c("straight","curly","wavy","mixed");
words_ast <- paste(words,"*",sep=""); #just get the "*" words

#make a loop according to positions of columns st,cur,wav,mix
for (j in 1:length(words_ast)){ #let's see if we can evaluate 2 in words_ast
  for (i in c(2,3,4)){ #but only in columns we selected
    a <- subset(hairdf,hairdf[,i]==words_ast[j]) #subset columns which satisfay condition. [Note that this can be written as hairdf %>% subset(.[,i]==words_ast[j]) ]
    hairdf[row.names(a),7+j] <- 2 #replace value from column 8
  }
}
#repeat process for "words"

for (j in 1:length(words)){
  for (i in c(2,3,4)){
    a <- subset(hairdf,hairdf[,i]==words[j])
    hairdf[row.names(a),7+j] <- 1
  }
}

这应该能让您得到预期的结果。或者,您可以使用 assign() 函数,即

assign(x,value=1)

其中 x 是单词中的每个元素。

所以在一个循环中:

assign(words[n],value=1) ; assign(words_ast[n],value=2)