3

我刚从R开始,虽然我一直做得很好,但是这个杀了我!:)

我有一个数据框:

df <- data.frame(
col1=letters[1:5],col2=c(NA,letters[4:1]),col3=letters[11:15],
col1_rr=letters[15:11], col2_rr=letters[2], col3_rr=c(letters[11:14], "oz"))

看起来像这样:

     col1      col2    col3    col1_rr  col2_rr  col3_rr
 1     a        NA       k        o        b        k
 2     b        d        l        n        b        l
 3     c        c        m        m        b        m
 4     d        b        n        l        b        n
 5     e        a        o        k        b        oz

请注意列名中的模式。对于每一列colX,都有一个colX_rr.

现在,我想检查 的内容df[1,"col1"]是否包含在df[1,"col1_rr"].

例如,此语句对于 是错误的df[1,"col1"],但对于所有col3单元格都是正确的(甚至df[5,"col3"],因为o包含在 中oz)。

我知道我可以使用grepl

 > grepl(df[1,"col3"], df[1,"col3_rr"])
 [1] TRUE
 > grepl(df[2,"col1"], df[2,"col1_rr"])
 [1] FALSE
 > grepl(df[1,"col2"], df[1,"col2_rr"])
 [1] NA
 > grepl(df[5,"col3"], df[5,"col3_rr"])
 [1] TRUE

接下来:一般来说,如果字符yfrom[z , colX]包含在等效[z , colX_rr]单元格中,那么我想创建一个新列y1为给定行输入。如果字符yfrom[z , colX]不包含在等效项中,则[z , colX_rr]输入0.df$y

所以我最后会有这样的事情:

     col1      col2    col3    col1_rr  col2_rr  col3_rr     a        b (...)  k(...)
 1     a        NA       k        o        b        k        0        0        1
 2     b        d        l        n        b        l        0        0        0
 3     c        c        m        m        b        m        0        0        0
 4     d        b        n        l        b        n        0        1        0
 5     e        a        o        k        b        oz       0        0        0

在列范围col1:col3的每个单元格中,只有一个字母,并且每个参与者(行)仅出现一次。column range col1_rr:的内容col3_rr非常混乱,包含不同长度的字符串,但每个字母对于每一行也只存在一次。

请注意,NA表中也出现了 s。

我希望这是自动化的,因为真实数据中有 50 列。但如有必要,我可以为每一列单独编写一行脚本。

实际数据中的字母来自 range letters[1:14],因此最后将只有 14 个新列,每个包含值 0 或 1(或TRUE/ FALSE,如果这使解决方案更简单)。

ifelse对于如此复杂的规则,我一直在尝试merge但不知道如何让它们解决这个问题。

谢谢!

4

1 回答 1

1

这是一个解决方案,但不是很优雅。它使用reshape2包:

df <- data.frame(col1=letters[1:5],col2=c(NA,letters[4:1]),col3=letters[11:15],
                 col1_rr=letters[15:11], col2_rr=letters[2], col3_rr=c(letters[11:14], "oz"))
col.vars <- names(df)[1:3]
colrr.vars <- names(df)[4:6]
df$id <- 1:nrow(df)
df.var <- melt(df[,c("id",col.vars)], id.vars="id")
df.var_rr<- melt(df[,c("id",colrr.vars)], id.vars="id")
let <- names(table(unlist(df[,1:3])))
m <- data.frame(sapply(let, function(l) df.var$value==l & grepl(l, df.var_rr$value)))
cbind(df, aggregate(m, list(df.var$id), sum))

这使 :

  col1 col2 col3 col1_rr col2_rr col3_rr id Group.1 a  b c d e k l m n o
1    a <NA>    k       o       b       k  1       1 0 NA 0 0 0 1 0 0 0 0
2    b    d    l       n       b       l  2       2 0  0 0 0 0 0 1 0 0 0
3    c    c    m       m       b       m  3       3 0  0 0 0 0 0 0 1 0 0
4    d    b    n       l       b       n  4       4 0  1 0 0 0 0 0 0 1 0
5    e    a    o       k       b      oz  5       5 0  0 0 0 0 0 0 0 0 1
于 2013-03-22T14:00:48.697 回答