我有一个相对较大的数据集,我想测试每个sting是否存在于从较大数据集创建的一系列子集数据帧中。 我能够通过三个步骤完成此任务,但我想编写一段代码,只需一步即可完成。
由于我想要的文件大小 创建子文件t2.a用于在我的文件t1中添加1或0,删除它; 然后重复t2.b,t2.c ...
的过程我的实际数据集类似于下面的数据帧。
t1 <- data.frame(A1 = c("red", "blue", "green", "yellow", "brown"),
A2 = c("orange", "purple", "yellow", "black", NA),
A3 = c(1,2,4,5,7))
t2 <- data.frame(B2 = c("black", "pink", "lime", "green", "grey", "mist", "blond", "grass", "violet", "red"),
B3 = c("a", "b", "a", "c", "d", "d", "a" , "c", "a", "b"))
> t1
A1 A2 A3
1 red orange 1
2 blue purple 2
3 green yellow 4
4 yellow black 5
5 brown <NA> 7
> t2
B2 B3
1 black a
2 pink b
3 lime a
4 green c
5 grey d
6 mist d
7 blond a
8 grass c
9 violet a
10 red b
我现有的代码分为三个步骤:
# step 1. creates a subset of files
for(i in unique(t2$B3)) {
colName <- paste("t2", i, sep = ".")
assign(colName, t2[t2$B3 == i, ])
}
# step2. find if string exist in a given subfile
t1$t2.a <- ifelse(t1$A1 %in% t2.a$B2 | t1$A2 %in% t2.a$B2, 1, 0)
#
t1$t2.b <- ifelse(t1$A1 %in% t2.b$B2 | t1$A2 %in% t2.b$B2, 1, 0)
#
t1$t2.c <- ifelse(t1$A1 %in% t2.c$B2 | t1$A2 %in% t2.c$B2, 1, 0)
#
t1$t2.d <- ifelse(t1$A1 %in% t2.d$B2 | t1$A2 %in% t2.d$B2, 1, 0)
# 3.remove each newly created data set
rm(t2.a)
rm(t2.b)
rm(t2.c)
rm(t2.d)
结果应该如下面的数据框:
A1 A2 A3 t2.a t2.b t2.c t2.d
1 red orange 1 0 1 0 0
2 blue purple 2 0 0 0 0
3 green yellow 4 0 0 1 0
4 yellow black 5 1 0 0 0
5 brown <NA> 7 0 0 0 0
答案 0 :(得分:2)
以下内容可实现您想要的结果。
我们不是多次重复相同的代码块,而是更改参数,而是利用R lapply
。
它实际上是lapply
内的几个步骤,但只需一次通话。
cbind(t1,
do.call(what = cbind,
args = lapply(unique(t2$B3), function(var_x){
colName <- paste("t2", var_x, sep = ".")
df <- assign(colName, t2[t2$B3 == var_x, ])
df_2 <- data.frame(ifelse(t1$A1 %in% df$B2|t1$A2 %in% df$B2, 1, 0))
colnames(df_2) <- paste("t2", as.character(var_x), sep = ".")
df_2})
)
)
答案 1 :(得分:1)
有很多方法可以做到这一点,但你需要一个[左]连接,然后扩展到宽范围。一个选项:
t3 <- merge(t1, t2, by.x = 'A1', by.y = 'B2', all.x = TRUE) # add matching values of B3
t3 <- merge(t1, xtabs(rep(1, nrow(t3)) ~ A1 + B3, t3)) # spread B3 with xtabs, rejoin
t3 <- tidyr::spread(t3, B3, Freq) # for the life of me I can't figure out stats::reshape
t3
## A1 A2 A3 a b c d
## 1 blue purple 2 0 0 0 0
## 2 brown <NA> 7 0 0 0 0
## 3 green yellow 4 0 0 1 0
## 4 red orange 1 0 1 0 0
## 5 yellow black 5 0 0 0 0
或者,如果您使用cbind
将as.data.frame.matrix
表格显式转换为data.frame,则可以使用xtabs
代替第二次加入和传播:
t3 <- merge(t1, t2, by.x = 'A1', by.y = 'B2', all.x = TRUE)
t3 <- cbind(t1, as.data.frame.matrix(xtabs(rep(1, nrow(t1)) ~ A1 + B3, t3)))
使用一些额外的rownames返回相同的内容。