如果满足条件,则循环粘贴列

时间:2014-07-11 13:53:47

标签: r for-loop paste

我想创建一个创建新列的循环,然后在单独的列中满足条件时将两列粘贴在一起。如果不满足条件,则列将等于现有列中的任何值。最后,我想删除旧列并重命名新列以匹配旧列。在下面的示例中,我创建了名为a1_t,a2_t,a3_t的列。然后,如果a1 == A,将a1和a1_c粘贴在一起并将值放在a1_t中,否则将值从a1复制到a1_t。对a2_t和a3_t重复此过程。

以下是数据:

set.seed(1)
dat <- data.frame(a1 = sample(LETTERS[1:9],15,replace=T),
                  a1_c = sample (1:100,15),
                  a2 = sample(LETTERS[1:9],15,replace=T),
                  a2_c = sample (1:100,15),
                  a3 = sample(LETTERS[1:9],15,replace=T),
                  a3_c = sample (1:100,15))

这是创建我的最终目标的最长方法:

dat$a1_t <- 'none'
dat$a1_t[dat$a1=="A"] <- paste((dat$a1[dat$a1=="A"]),(dat$a1_c[dat$a1=="A"]),sep="_")
dat$a1_t[dat$a1=="B"] <- 'B'
dat$a1_t[dat$a1=="C"] <- 'C'
dat$a1_t[dat$a1=="D"] <- 'D'
dat$a1_t[dat$a1=="E"] <- 'E'
dat$a1_t[dat$a1=="F"] <- 'F'
dat$a1_t[dat$a1=="G"] <- 'G'
dat$a1_t[dat$a1=="H"] <- 'H'
dat$a1_t[dat$a1=="I"] <- 'I'

dat$a2_t <- 'none'
dat$a2_t[dat$a2=="A"] <- paste((dat$a2[dat$a2=="A"]),(dat$a2_c[dat$a2=="A"]),sep="_")
dat$a2_t[dat$a2=="B"] <- 'B'
dat$a2_t[dat$a2=="C"] <- 'C'
dat$a2_t[dat$a2=="D"] <- 'D'
dat$a2_t[dat$a2=="E"] <- 'E'
dat$a2_t[dat$a2=="F"] <- 'F'
dat$a2_t[dat$a2=="G"] <- 'G'
dat$a2_t[dat$a2=="H"] <- 'H'
dat$a2_t[dat$a2=="I"] <- 'I'

dat$a3_t <- 'none'
dat$a3_t[dat$a3=="A"] <- paste((dat$a3[dat$a3=="A"]),(dat$a3_c[dat$a3=="A"]),sep="_")
dat$a3_t[dat$a3=="B"] <- 'B'
dat$a3_t[dat$a3=="C"] <- 'C'
dat$a3_t[dat$a3=="D"] <- 'D'
dat$a3_t[dat$a3=="E"] <- 'E'
dat$a3_t[dat$a3=="F"] <- 'F'
dat$a3_t[dat$a3=="G"] <- 'G'
dat$a3_t[dat$a3=="H"] <- 'H'
dat$a3_t[dat$a3=="I"] <- 'I'

-al

1 个答案:

答案 0 :(得分:4)

如果您要处理少量列,则可能只想使用withinifelse,如下所示:

within(dat, {
  a1_t <- ifelse(a1 == "A", paste(a1, a1_c, sep = "_"), 
                 as.character(a1))
  a2_t <- ifelse(a2 == "A", paste(a2, a2_c, sep = "_"), 
                 as.character(a2))
  a3_t <- ifelse(a3 == "A", paste(a3, a3_c, sep = "_"), 
                 as.character(a3))
})

但是,如果有必要,您可以以编程方式扩展这个想法。

我在下面的代码中添加了评论,以便您可以看到它正在做什么。

## What variables are we checking?
checkMe <- c("a1", "a2", "a3")

## Let's convert those to character first
dat[checkMe] <- lapply(dat[checkMe], as.character)
cbind(dat,                  ## We'll combine the original data using cbind
      setNames(             ## setNames is for the resulting column names
        lapply(checkMe, function(x) {    ## lapply is an optimized loop
          Get <- c(x, paste0(x, "_c"))   ## We need this for the "if" part
          ifelse(dat[, x] == "A",        ## logical comparison
                 ## if matched, paste together the value from
                 ## the relevant column
                 paste(dat[, Get[1]], dat[, Get[2]], sep = "_"),
                 dat[, x])               ## else return the original value
        }), 
        paste0(checkMe, "_t")))          ## the column names we want
#    a1 a1_c a2 a2_c a3 a3_c a1_t a2_t a3_t
# 1   C   50  E   79  I   90    C    E    I
# 2   D   72  F    3  C   86    D    F    C
# 3   F   98  E   47  E   39    F    E    E
# 4   I   37  B   72  C   76    I    B    C
# 5   B   75  H   67  F   93    B    H    F
# 6   I   89  G   46  C   42    I    G    C
# 7   I   20  H   81  E   67    I    H    E
# 8   F   61  A   41  G   38    F A_41    G
# 9   F   12  G   23  A   30    F    G A_30
# 10  A   25  D    7  H   69 A_25    D    H
# 11  B   35  H    9  D   19    B    H    D
# 12  B    2  F   29  H   64    B    F    H
# 13  G   34  H   95  D   11    G    H    D
# 14  D   76  E   58  D   22    D    E    D
# 15  G   30  E   35  E   13    G    E    E