【问题标题】:fill values of a column with values from another column (but not on the same row), conditionally, in R有条件地,在R中用另一列(但不在同一行)的值填充列的值
【发布时间】:2015-03-28 17:29:29
【问题描述】:

我有一个关于如何有条件地用另一列(但不在同一行)的值填充列的值的问题。 让我用我的数据集示例来解释这种情况。 这是我的数据集,其中两个人 (ID) 列进行了二元战斗(fight_id 列)。对于每场战斗,我有两条线(每人一条)。我想要做的是在每一行中填写“对手”列,并使用同一战斗 ID 中的另一个人的 ID。所以我想以粗体生成数据。

ID FIGHT_ID V3 OPP
12 -- 1 -------- 1 -- 13
13 -- 1 -------- 0 -- 12
14 -- 2 -------- 0 -- 15
15 -- 2 -------- 1 -- 14

我要写对手的名字(填OPP栏),意思是在OPP栏中复制参与同一战斗的其他个人的ID。我基本上是将个人转换为彼此的对手。 我想在同一个战斗 id 中分配一个 1 或 0 的列,然后在所有数据集的战斗 id 中创建一个循环,以执行类似的操作 :“如果 v3 = 1,则复制 v3 = 0 的 ID 的值,如果 v3 = 0,则复制 v3 = 1 的 ID 的值”。 这个概念很简单,但我似乎无法弄清楚(如果它们在同一行,我可以,但在这里我们必须在另一行中寻找一个值)。 在 R 语言中,我想这样做:

for(i in 1:nrow(data)){ for (j in 1:length(levels(data$Fight_ID))) { data$OPP[i] data$ID[i] else if (data$v3[i]==0) data $ID[i] }

除了在粗体部分,我想写 data$ID[i] 的值但是 v3 == 0 ,反之亦然第二个粗体。 如果它存在,它将类似于 "data$ID[i] where data$v3[i]==0" 。

显然还有其他方法可以做到这一点,但根据我所拥有的 R 知识,这对我来说似乎是合乎逻辑的。 谢谢您的帮助! 弗朗西斯卡

【问题讨论】:

  • 弗朗西斯卡欢迎来到 stackoverflow。请使用{} 按钮正确格式化您问题中的代码sn-ps。

标签: r loops conditional


【解决方案1】:

使用plyr,假设每个id 只有2 行:

df = data.frame(id=12:15, fight_id=c(1,1,2,2), v3=c(1,0,0,1))
#  id fight_id v3
#1 12        1  1
#2 13        1  0
#3 14        2  0
#4 15        2  1

library(plyr)
ldply(split(df, df$fight_id), function(u) transform(u, opp=rev(u$id)))

#  .id id fight_id v3 opp
#1   1 12        1  1  13
#2   1 13        1  0  12
#3   2 14        2  0  15
#4   2 15        2  1  14

或基础R:

do.call(rbind, lapply(split(df, df$fight_id), function(u) transform(u, opp=rev(u$id))))

#    id fight_id v3 opp
#1.1 12        1  1  13
#1.2 13        1  0  12
#2.3 14        2  0  15
#2.4 15        2  1  14

或者data.table:

library(data.table)
rbindlist(lapply(split(df, df$fight_id), function(u) transform(u, opp=rev(u$id))))

#   id fight_id v3 opp
#1: 12        1  1  13
#2: 13        1  0  12
#3: 14        2  0  15
#4: 15        2  1  14

还是data.table:

library(data.table)
setDT(df)[,opp:=rev(id), by=fight_id]

#> df
#   id fight_id v3 opp
#1: 12        1  1  13
#2: 13        1  0  12
#3: 14        2  0  15
#4: 15        2  1  14

还有一个非常有趣的没有循环的基础 R :)

df     = df[order(df$id),]
df$opp = df$id[rep(seq(0,length(df)/2,2), each=2)+2:1]

#> df
#  id fight_id v3 opp
#1 12        1  1  13
#2 13        1  0  12
#3 14        2  0  15
#4 15        2  1  14

【讨论】:

  • 好吧,除了 dplyr 之外,您涵盖了所有内容 :-) df %>% group_by(fight_id) %>% mutate(opp=rev(id))
  • 我知道你有 :) 我不是 dplyr 的忠实粉丝,因为它不是反射!
  • 非常感谢,它成功了!我使用了第一个,因为它看起来更紧凑。
猜你喜欢
  • 2012-05-29
  • 2017-06-22
  • 1970-01-01
  • 2022-07-27
  • 2016-08-01
  • 2019-03-14
  • 2022-01-15
  • 1970-01-01
相关资源
最近更新 更多