我只是从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]
,如果这使解决方案更简单)。
我一直在尝试使用TRUE
和FALSE
但不知道如何让它们适用于这个问题,对于这样一个复杂的规则。
谢谢!
答案 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