【问题标题】:Conditional value assignment to multiple columns based on some other column value基于某些其他列值对多个列进行条件值分配
【发布时间】:2017-02-26 05:28:07
【问题描述】:

我一直被这个问题困扰,我相信对于你们中的一些人来说,这不会太难解决。我在这个论坛上没有成功找到答案。

我工作的公司有一个轮岗计划,在该计划中,员工在多个部门工作一段时间,在某个时期结束时,他们会获得更高级别部门的评估(晋升)。大多数人将在 3 年内完成他们的课程,然后在第 4 和第 5 年完成更多课程。一小部分(约 15%)没有完成该计划。数据集相当大,可以追溯到 30 多年前。有些数据是手动输入的,容易出现数据输入错误。 cont1cont2、...、cont7 列标记个人是否仍在轮换计划中。如果员工分别在 3 年、4 年和 5 年内成功完成计划,prom3prom4prom5 列的 'Y'。所以'Y' in prom3 意味着'Y'prom4prom5 中也会有一个NAcont3,...,cont7 因为这个人是不再在轮换计划中。如果个人在第 3 年没有升职,而是在第 4 年升职,则 prom4'Y'cont4,...,cont7NA。现在你看到了问题。问题是我还有很多年。我知道我可以使用ifelse(),但代码变得非常混乱和冗长。我想以更优雅的方式动态地找到解决方案。

如果prom3 有一个'Y' 然后cont2'Y' 并且cont3,...,cont7NA,我需要找到一种动态编程的方法。如果idprom4 中有'Y',则cont4,...,cont7NAcont2cont3'Y' 等等。比如:

contYears <- seq(2,7, by=1)

promYears <- seq(3,5, by=1)

if (paste0("prom",promYears)=='Y'){
is.na(paste0("cont",contYears)) while contYears >= promYears)}
else paste0("cont",contYears)=='Y'

对不起,上面的尝试不太优雅!

谢谢你的帮助!!!下面是一个玩具df:

set.seed(123)
df <- tibble::data_frame(id = seq(1,100, by=1),
                     cont2 = sample(c('Y', NA), 100, replace=T, prob = c(0.9, 0.1)),
                     cont3 = sample(c('Y', NA), 100, replace=T, prob = c(0.8, 0.2)),
                     cont4 = sample(c('Y', NA), 100, replace=T, prob = c(0.5, 0.5)),
                     cont5 = sample(c('Y', NA), 100, replace=T, prob = c(0.25,0.75)),
                     cont6 = sample(c('Y', NA), 100, replace=T, prob = c(0.15,0.85)),
                     cont7 = sample(c('Y', NA), 100, replace=T, prob = c(0.10,0.9)),
                     prom3 = sample(c('Y', NA), 100, replace=T, prob = c(0.5,0.5)),
                     prom4 = sample(c('Y', NA), 100, replace=T, prob = c(0.75,0.25)),
                     prom5 = sample(c('Y', NA), 100, replace=T, prob = c(0.85,0.15)))

head(df) 

id cont2 cont3 cont4 cont5 cont6 cont7 prom3 prom4 prom5
1     Y     Y     Y  <NA>     Y  <NA>  <NA>  <NA>     Y
2     Y     Y     Y     Y  <NA>  <NA>     Y     Y     Y
3     Y     Y     Y  <NA>     Y  <NA>  <NA>     Y     Y
4     Y     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y
5     Y     Y     Y  <NA>  <NA>  <NA>  <NA>     Y     Y
6  <NA>     Y  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>

下面是输出的样子:

id cont2 cont3 cont4 cont5 cont6 cont7 prom3 prom4 prom5
1     Y     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y
2     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y     Y     Y 
3     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y     Y
4     Y     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y
5     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y     Y
6     Y     Y     Y     Y     Y     Y  <NA>  <NA>  <NA>

所以prom[:digit:] 触发cont[:digit:] 列到'Y'NA。如果有人在 3 年内升职,那么其他升职栏当然也是'Y'。正如我之前所说,我可以使用 ifelse() 语句来做到这一点,但我有超过 7 年的 cont[:digit:] 和 5 年的 prom[:digit:] 这使得代码非常难以阅读和耗时。

【问题讨论】:

  • 您能根据示例显示您的预期输出吗?
  • 请编辑您的帖子并在那里更新
  • 如果你只是用prom列中已经包含的数据填充它们,似乎所有cont列都无关紧要。
  • 我认为你的 'cont6' 应该是预期输出中 id 3 的 NA
  • 嗨,阿克伦,是的。刚刚更正。

标签: arrays r loops if-statement


【解决方案1】:

我们可以通过apply 做到这一点

df[grep("cont", names(df))] <- t(apply(df[-1], 1, FUN= function(x) {
         i1 <- seq_len(6)>which.max(x[7:9]=="Y")
       if(length(i1)>0) replace(x[1:6], i1, NA) else rep("Y", 6)}))
head(df, 6)
#   id cont2 cont3 cont4 cont5 cont6 cont7 prom3 prom4 prom5
#1  1     Y     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y
#2  2     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y     Y     Y
#3  3     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y     Y
#4  4     Y     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y
#5  5     Y     Y  <NA>  <NA>  <NA>  <NA>  <NA>     Y     Y
#6  6     Y     Y     Y     Y     Y     Y  <NA>  <NA>  <NA>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-20
    • 2018-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多