R比较相应的单元格并创建以内容命名的新列

时间:2013-03-22 13:31:01

标签: r dataframe

我只是从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"],此声明为false,但对于所有col3个单元格都为true(偶数为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

接下来:一般来说,如果来自y的{​​{1}}字符包含在等效的[z , colX]单元格中,那么我想创建一个新列[z , colX_rr]并输入{对于给定的行,{1}}。如果y中的字符1未包含在等效y中,则在[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的内容非常混乱,包含不同长度的字符串,但每行的每个字母只存在一次。

请注意,col1_rr也出现在表格中。

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

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

我一直在尝试使用TRUEFALSE但不知道如何让它们适用于这个问题,对于这样一个复杂的规则。

谢谢!

1 个答案:

答案 0 :(得分: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