【发布时间】:2019-10-24 14:44:34
【问题描述】:
我不是很有经验的 R 用户,所以请寻求建议如何优化我已构建的内容以及继续前进的方向。
我有一个reference数据框,它包含四列整数值和一个ID。
df <- matrix(ncol=5,nrow = 10)
colnames(df) <- c("A","B","C","D","ID")
# df
for (i in 1:10){
df[i,1:4] <- sample(1:5,4, replace = TRUE)
}
df <- data.frame(df)
df$ID <- make.unique(rep(LETTERS,length.out=10),sep='')
df
A B C D ID
1 2 4 3 5 A
2 5 1 3 5 B
3 3 3 5 3 C
4 4 3 1 5 D
5 2 1 2 5 E
6 5 4 4 5 F
7 4 4 3 3 G
8 2 1 5 5 H
9 4 4 1 3 I
10 4 2 2 2 J
第二个数据框有手动输入,是用户输入,我想稍后把它变成闪亮的应用程序,这也是我要求优化的原因,因为我的代码对我来说似乎不是很整洁。
df.man <- data.frame(matrix(ncol=5,nrow=1))
colnames(df.man) <- c("A","B","C","D","ID")
df.man$ID <- c("man")
df.man$A <- 4
df.man$B <- 4
df.man$C <- 3
df.man$D <- 4
df.man
A B C D ID
4 4 3 4 man
我想按照规则从引用中依次过滤行:
如果在 reference 表和 manual 之间的整行中存在完全匹配,则从参考中提取此(那些)并显示该行,如果没有,则减少数量从右到左匹配列,直到存在匹配但不在少于两个变量(列 A,B)之间。
所以以我有限的知识,我写了这个:
# subtraction manual from reference
df <- df %>% dplyr::mutate(Adiff=A-df.man$A)%>%
dplyr::mutate(Bdiff=B-df.man$B)%>%
dplyr::mutate(Cdiff=C-df.man$C) %>%
dplyr::mutate(Ddiff=D-df.man$D)
# check manually how much in a row has zero difference and filter those
ifelse(nrow(df%>%filter(Adiff==0 & Bdiff==0 & Cdiff==0 & Ddiff==0)) != 0,
df0<-df%>%filter(Adiff==0 & Bdiff==0 & Cdiff==0 & Ddiff==0),
ifelse(nrow(df%>%filter(Adiff==0 & Bdiff==0 & Cdiff==0)) != 0,
df0<-df%>%filter(Adiff==0 & Bdiff==0 & Cdiff==0),
ifelse(nrow(df%>%filter(Adiff==0 & Bdiff==0)) != 0,
df0<-df%>%filter(Adiff==0 & Bdiff==0),
"less then two exact match")
))
tbl_df(df0[,1:5])
# A tibble: 1 x 5
A B C D ID
<int> <int> <int> <int> <chr>
1 4 4 3 3 G
它可以工作并找到 ID G,但在我看来很难看。所以第一个问题是 - 有什么推荐的方法来改进它?有没有我缺少的功能、包或东西?
第二个问题 - 我想把情况复杂化。
假设我们有参考数据集。
A B C D ID
2 4 3 5 A
5 1 3 5 B
3 3 5 3 C
4 3 1 5 D
2 1 2 5 E
5 4 4 5 F
4 4 3 3 G
2 1 5 5 H
4 4 1 3 I
4 2 2 2 J
手动输入是
A B C D ID
4 4 2 2 man
过滤规则应如下:
如果在 reference 表和 manual 之间的整行中存在完全匹配,则从参考中提取此(那些)并向我显示该行,如果没有然后从右到左减少匹配列的数量,直到存在匹配但不是在少于两个变量(列 A,B)之间。
从我只有两个变量匹配的那些行中过滤那些在右侧的列中有 ± 1 差异的行。所以我应该从上面示例的参考表中过滤大小写 G 和 I。
继续我上面的做法,我会做以下事情:
ifelse(nrow(df0%>%filter(Cdiff %in% (-1:1) & Ddiff %in% (-1:1)))>0,
df01 <- df0%>%filter(Cdiff %in% (-1:1) & Ddiff %in% (-1:1)),
ifelse(nrow(df0%>%filter(Cdiff %in% (-1:1)))>0,
df01<- df0%>%filter(Cdiff %in% (-1:1)),
"NA"))
最后大约有 11 列,但我认为这并不重要。
牢记这一目标 - 您建议如何进行? 谢谢!
【问题讨论】:
-
你能澄清第二个问题的第二个规则吗?这适用于“只有四个变量匹配”的情况 --- 但看起来您将 +/-1 差异应用于有 2 个匹配项的 G 和 I?您的意思是只有“2 个变量匹配”A 和 B?
-
是的,我想我搞砸了,我的意思是在那个特定的例子中有 2 个变量匹配,但将来我将有 11 个变量并且希望至少有 4 个匹配。我会更新帖子中的文字。
标签: r filter conditional-statements