在R代码中创建基于多个变量的新变量条件

3

我有一个名为“dat”的数据集。

TEAM1  TEAM2    WINNER

A       P       A
I       S       I
P       S       S
S       I       I
S       P       P
W       P       W
A       E       A
A       S       S
E       A       E

我想使用R代码创建变量“LOSER”。我尝试过这样:
Loser <- NULL

    for (i in 1: nrow(dat)){
        if(match(dat$Team1[i],dat$Winner)==TRUE){
            Loser[i] <- cricket$Team2[i]
        }else if(match(dat$Team1[i],dat$Winner)==FALSE ){
            Loser[i] <- dat$Team1[i] 
        }
            }

但是这个代码并不能给出精确的结果。这个代码有什么问题吗?

期望输出:

TEAM1  TEAM2   WINNER LOSER 

A       P       A      P
I       S       I      S 
P       S       S      P
S       I       I      S
S       P       P      S
W       P       W      P
A       E       A      E
A       S       S      A
E       A       E      A

3
非常抱歉,我无法理解您的要求。您能否提供更具体的内容或指示? - David Arenburg
我希望输出为 Loser= (P, S, P, S, S, P, E, A, A)。 - Rudro88
尝试执行 dat[1:2][cbind(1:nrow(dat),with(dat, TEAM1==WINNER)+1L)] - akrun
@Akrun 这段代码没有正常工作。谢谢。 - Rudro88
你能否尝试使用我解决方案中发布的数据? - akrun
2个回答

4

我们可以通过将“TEAM1”与“WINNER”列进行比较来获得所需的输出。将其加1,以强制使用“FALSE / TRUE”转换为“1/2”。这可用作列索引。然后,我们可以使用行号结合cbind获取相应的元素,以创建“LOSER”列。

 dat$LOSER <- dat[cbind(1:nrow(dat), with(dat, TEAM1 == WINNER) + 1)]
 dat$LOSER
 #[1] "P" "S" "P" "S" "S" "P" "E" "A" "A"

注意:根据@David Arenburg的评论进行修改。此外,在数据集中,第一列和第二列是“TEAM1”和“TEAM2”。如果我们有一个包含许多列且这些列不在第一和第二位置的数据集,则可以像我在注释中展示的那样对数据集进行子集化,只保留两列。

 dat$LOSER <- dat[paste0('TEAM', 1:2)][cbind(1:nrow(dat),
                                with(dat, TEAM1==WINNER)+1L)]

使用 data.table 的另一个选项。对于 TEAM1==WINNER 中的 TRUE 值,我们将 'LOSER' 分配为 'TEAM2' (:=)。然后,我们用 'TEAM1' 替换 'LOSER' 中的 NA 值。

  library(data.table)
  setDT(dat)[TEAM1==WINNER, LOSER:= TEAM2][is.na(LOSER), LOSER:= TEAM1]
  dat

数据

 dat <- structure(list(TEAM1 = c("A", "I", "P", "S", "S", "W", "A", "A", 
 "E"), TEAM2 = c("P", "S", "S", "I", "P", "P", "E", "S", "A"), 
 WINNER = c("A", "I", "S", "I", "P", "W", "A", "S", "E")),
 .Names =   c("TEAM1", 
 "TEAM2", "WINNER"), class = "data.frame", row.names = c(NA, -9L))

2

我忍不住要用dplyr的方式写下这段代码。

library(dplyr)
dat %>% 
     mutate(LOSER = ifelse(TEAM1 == WINNER, TEAM2, TEAM1))
  TEAM1 TEAM2 WINNER LOSER
1     A     P      A     P
2     I     S      I     S
3     P     S      S     P
4     S     I      I     S
5     S     P      P     S
6     W     P      W     P
7     A     E      A     E
8     A     S      S     A
9     E     A      E     A

2
不,我认为这里不需要 dplyr,只需执行 transform(df, LOSER = ifelse(TEAM1 == WINNER, TEAM2, TEAM1)) 即可。 - David Arenburg
@DavidArenburg 我同意,我应该首先考虑基本的R解决方案。 - SabDeM
dplyr在基础R变得混乱或需要进行不同分组操作时非常好用,但是transform更加优美且高效。 - David Arenburg
@DavidArenburg 我不知道这一点。我以为 transform 就像基本的 R reshape 一样:丑陋而缓慢。 - SabDeM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接