这与这里的一个常见问题有关,我认为它有一个简单的答案,但我有些困惑。
我希望根据其他两列在R中填充新列。通常,我会写条件以及基于这些条件的结果,然后将其指向新列。但是,在这种情况下,我尝试填写已经拥有的值,它们只是在另一行中。这是一个示例:
Example Dataset:
df <- data.frame(Candidate = c("Allison" , "Bob" , "Ralph" , "Doug" , "Ben"), State = c("NY" , "NJ" , "NY" , "FL" , "FL"), District = c(1,3,1,2,2), Party = c(1,2,1,1,2), Trait1 = c(5,4,3,2,3), Trait2 = c(5,3,2,5,4))
> print(df)
Candidate State District Party Trait1 Trait2
1 Allison NY 1 1 5 5
2 Bob NJ 3 2 4 3
3 Ralph NY 1 1 3 2
4 Doug FL 2 1 2 5
5 Ben FL 2 2 3 4
我想遍历每个候选人,为包含相同地区和州的候选人填充一个包含Trait1的新列。
Candidate State District Party Trait1 Trait2 Opponent.Trait1
1 Allison NY 1 1 5 5 3
2 Bob NJ 3 2 4 3 NA
3 Ralph NY 1 1 3 2 5
4 Doug FL 2 1 2 5 3
5 Ben FL 2 2 3 4 2
我不确定如何将df $ Trait1用作此操作的输出。我认为这是一个简单的问题,但我不知道该怎么做。
答案 0 :(得分:3)
如果您最多只能拥有1个对手,则可以反转每个组中的trait列以获得预期结果。
ave(df$Trait1, df[c("State","District")], FUN=function(x) if(length(x)==1) NA else rev(x) )
#[1] 3 NA 5 3 2
如果您不介意发出警告,则可以将其缩短为:
ave(df$Trait1, df[c("State","District")], FUN=function(x) x[2:1] )
无论如何,在dplyr
中,相同的逻辑成立:
df %>%
group_by(State,District) %>%
mutate(optrait = if(n()==1) NA else rev(Trait1) )
在data.table
中:
setDT(df)
df[, optrait := if(.N==1) NA_real_ else rev(Trait1), by=.(State,District)]
data.table
中的更新联接对于复制候选行可能更健壮,但是我的解决方案有点难看:
df[, optrait :=
df[
df, on=c("State","District"),
if(.N==1) NA_real_ else Trait1[Candidate!=i.Candidate],
by=.EACHI
]$V1
]
答案 1 :(得分:2)
这是使用dplyr
的幼稚解决方案:
library(dplyr)
df %>%
group_by(State, District) %>%
mutate(Opponent.Trait1 = ifelse(Trait1 == min(Trait1), ifelse(Trait1 == max(Trait1), NA, max(Trait1)), min(Trait1)))
# # Groups: State, District [3]
# Candidate State District Party Trait1 Trait2 Opponent.Trait1
# <fct> <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 Allison NY 1 1 5 5 3
# 2 Bob NJ 3 2 4 3 NA
# 3 Ralph NY 1 1 3 2 5
# 4 Doug FL 2 1 2 5 3
# 5 Ben FL 2 2 3 4 2