我有一张这样的桌子:
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.table
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
你知道我该怎么做到吗?
答案 0 :(得分:2)
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
这为我们提供了前四列中具有两个“所需”模式之一的实例。我们要在列的 any 中有行,因此我们对它们进行“ any”:
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”,直接将它们与&
进行逻辑链接。
答案 1 :(得分:1)
这绝不比工作的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函数对数据逐行应用一个函数。
答案 2 :(得分:1)
类似于上一个答案:
apply(data[, 1:4], 1, function(a) any(a %in% c("0/1","1/0")) && !any(a[1:3] == "./.")) & data$f == "L"
答案 3 :(得分:1)
另一个选择:
data[f=="L", .SD[apply((.SD=="1/0" | .SD=="0/1") & !apply(.SD=="./.",1,any), 1, any)],
.SDcols=c("a","b","c","d")]
答案 4 :(得分:0)
这是使用基数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
答案 5 :(得分:0)
您可以首先将列a
,b
,c
和d
串联在一起。
data[, abcd := paste(a, b, c, d)]
然后,我将创建另一个新列,该列将告诉我是否满足条件。我首先将其设置为所有FALSE
。
data[, Selection := F]
接下来,仅为满足条件的列分配TRUE
。
(1)在"0/1"
,"1/0"
,a
或b
或c
中有d
或abcd
}
(2)在"./."
中没有abcd
(3)在"L"
列中有f
data[(grepl("0/1", abcd) | grepl("1/0", abcd)) & !grepl("\\./\\.", abcd) &
f == "L",
Selection := T]
从这里,我可以选择所需的行
data[(Selection), ]