我有一个这样的表:
data <- data.frame(a = c("0/0", "0/1", "0/0", "0/0" ),
b = c("0/1", "./.", "0/1", "0/0"),
c = c("1/0", "0/0", "1/1", "0/0"),
d = c("1/0", "0/0", "1/1", "0/0"),
f = c("L", "L", "T", "L"))
我希望选择至少包含一个0/1或1/0且没有的任何行。/。在列a、b和c中,并且在列f中匹配L。
我正在使用库数据进行尝试。表
data[data$a %like% "0/1|1/0" | data$b %like% "0/1|1/0"| data$c %like% "0/1|1/0" & !(data$a %like% "./.") & !(data$b %like% "./.") & !(data$c %like% "./.") & data$f == "L", ]
但它不起作用。
表格如下:
a b c d f
1 0/0 0/1 1/0 1/0 L
2 0/1 ./. 0/0 0/0 L
3 0/0 0/1 1/1 1/1 T
4 0/0 0/0 0/0 0/0 L
所需的输出应该是这样的:
a b c d f
1 0/0 0/1 1/0 1/0 L
你知道我是怎么做到的吗?
data[ apply(sapply(data[1:4], `%in%`, c('0/1','1/0')), 1, any) &
apply(sapply(data[1:3], Negate(`%in%`), c('./.')), 1, all) &
data$f == "L", ]
# a b c d f
# 1 0/0 0/1 1/0 1/0 L
分解:
sapply(data[1:4], `%in%`, c('0/1','1/0'))
# a b c d
# [1,] FALSE TRUE TRUE TRUE
# [2,] TRUE FALSE FALSE FALSE
# [3,] FALSE TRUE FALSE FALSE
# [4,] FALSE FALSE FALSE FALSE
这为我们提供了前四列中具有两个"所需"模式之一的实例。我们想要任何列都有它的行,所以我们在它们之间"任意":
apply(sapply(data[1:4], `%in%`, c('0/1','1/0')), 1, any)
# [1] TRUE TRUE TRUE FALSE
同样,找到那些有"不想要"模式的:
sapply(data[1:3], Negate(`%in%`), c('./.'))
# a b c
# [1,] TRUE TRUE TRUE
# [2,] TRUE FALSE TRUE
# [3,] TRUE TRUE TRUE
# [4,] TRUE TRUE TRUE
apply(sapply(data[1:3], Negate(`%in%`), c('./.')), 1, all) # notice "all", not "any"
# [1] TRUE FALSE TRUE TRUE
现在我们希望"L"在最后一列(=="L"
(中,直接将它们与&
逻辑链接。
这绝不比工作的data.table解决方案快,但它适用于基本R:
dat <- data.frame(a = c("0/0", "0/1", "0/0", "0/0" ),
b = c("0/1", "./.", "0/1", "0/0"),
c = c("1/0", "0/0", "1/1", "0/0"),
d = c("1/0", "0/0", "1/1", "0/0"),
f = c("L", "L", "T", "L"))
dat
f <- which(colnames(dat) == 'f')
rows <- apply(dat, 1, function(x) x[f] == "L" & !any("./." == x[-f]) & any("0/1" == x[-f]) | any("1/0" == x[-f]) )
dat[rows,]
它使用apply函数对数据逐行应用函数。
另一个选项:
data[f=="L", .SD[apply((.SD=="1/0" | .SD=="0/1") & !apply(.SD=="./.",1,any), 1, any)],
.SDcols=c("a","b","c","d")]
类似于前面的答案:
apply(data[, 1:4], 1, function(a) any(a %in% c("0/1","1/0")) && !any(a[1:3] == "./.")) & data$f == "L"
下面是一个使用基于R-的apply
的简单解决方案
test <- apply(data, 1, function(x) {
any(x %in% c("0/1", "1/0")) & !any(x == "./.") & x["f"] == "L"
})
data[test, ]
# a b c d f
# 1 0/0 0/1 1/0 1/0 L
您可以首先将列a
、b
、c
和d
连接在一起。
data[, abcd := paste(a, b, c, d)]
然后,我会创建另一个新的专栏,告诉我是否满足条件。我首先将其设置为所有FALSE
。
data[, Selection := F]
接下来,只为满足条件的列分配TRUE
。
(1( 在a
、b
、c
或d
中具有"0/1"
或"1/0"
,或仅具有abcd
(2(abcd
中没有"./."
(3( 在f
列中具有"L"
data[(grepl("0/1", abcd) | grepl("1/0", abcd)) & !grepl("\./\.", abcd) &
f == "L",
Selection := T]
从这里,我可以选择需要的行
data[(Selection), ]