新列的条件是数字是均匀/不均匀和列

时间:2017-11-01 10:36:44

标签: r conditional-statements

说我有以下df:

{
"Plaintext": "E0kmokU0HEhIujfSPxKyUhjnBbCiK/a98/+B6G3Ux0KJdc=", 
"KeyId": "arn:aws:kms:us-west-2:XXXXXXXXXXX:key/XXxxxXX-06ce-49f1-3452-XXxxxXXXXxx"

我想添加一个新的列,其字符值取决于id号是否为偶数,以及字符串' signal'以'名称'到达列。

对于不均匀的ID号码,以及最多包含'信号'列名称'我想要角色T.在信号之后,角色应该变成C'。

对于偶数ID号码,以及包含“信号”的信号。列名称'我想要角色C.在信号之后,角色应该变成“T'。

对于给出的示例,这应该导致以下data.frame:

id<-rep(1:2,c(7,6))
name<-c('a','t','signal','b','s','e','signal','x','signal','r','s','t','signal')

   id   name
1   1      a
2   1      t
3   1 signal
4   1      b
5   1      s
6   1      e
7   1 signal
8   2      x
9   2 signal
10  2      r
11  2      s
12  2      t
13  2 signal

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:0)

我们可以使用%%==来创建列

library(dplyr)
df1 %>%
    group_by(id) %>%
    mutate(ind = (cumsum(lag(name, default = name[1]) == 'signal')>0) + 1, 
           condition = c('T', 'C')[ifelse(id %%2 > 0, ind, 
                 as.integer(factor(ind, levels = rev(unique(ind)))))] ) %>% 
    select(-ind)
# A tibble: 13 x 3
# Groups:   id [2]
#      id   name condition
#   <int>  <chr>     <chr>
# 1     1      a         T
# 2     1      t         T
# 3     1 signal         T
# 4     1      b         C
# 5     1      s         C
# 6     1      e         C
# 7     1 signal         C
# 8     2      x         C
# 9     2 signal         C
#10     2      r         T
#11     2      s         T
#12     2      t         T
#13     2 signal         T

数据

df1 <- data.frame(id, name, stringsAsFactors=FALSE)

答案 1 :(得分:0)

这不是一个矢量化的解决方案,但对我来说它似乎是一个令人讨厌的代码。

数据准备 - 我添加新列来描述条件

id<-rep(1:2,c(7,6))
name<-c('a','t','signal','b','s','e','signal','x','signal','r','s','t','signal')
df <- data.frame(id, name)
df$condition <- rep("X", nrow(df))

我需要控制两种状态:(i)signal是否已切换; (ii)如果身份证改变last(从偶数到奇数和其他方式)。然后我逐行阅读并更新条件状态和两个变量。

signal <- F
last <- 1
for (i in 1:nrow(df)){
    # id changed - reset signal
    if (last != (df[i, "id"] %% 2)) signal <- F
    if(!signal){
        df[i,"condition"] <- ifelse(df[i,"id"] %% 2, "T", "C")
    } else {
        df[i, "condition"] <- ifelse(df[i,"id"] %% 2, "C", "T")
    }
    # signal is on
    if (df[i, "name"] == "signal") signal <- T
    # save last id (even or odd)
    last <- df[i, "id"] %% 2
}

我希望它有所帮助。

答案 2 :(得分:0)

另一种方法可能是

id <- rep(1:2,c(7,6))
name <- c('a','t','signal','b','s','e','signal','x','signal','r','s','t','signal')
df <- data.frame(id, name)

library(dplyr)
df %>% 
  group_by(id) %>%
  mutate(FirstSignalIndex=min(which(name=='signal'))) %>%
  mutate(condition = ifelse((id %% 2)==0, 
                      ifelse(row_number()>FirstSignalIndex, 'T', 'C'),
                      ifelse(row_number()>FirstSignalIndex, 'C', 'T'))) 


希望这有帮助!