我有以下数据集
dat <- data.frame(group = c(1,1,1,1,1), id = c(1,2,3,4,5),
t1 = c('a','a','b','b','c'),p1 = c(0.98,1,0.5,0.9,1),
t2 = c('b',NA,'a','c',NA),p2 = c(0.02,NA,0.25,0.10,NA),
t3 = c(NA,NA,'c',NA,NA),p3 = c(NA,NA,0.25,NA,NA))
我试图计算包含多行(变量='group')的组中多列(t1,t2,t3)中出现的唯一字符的数量。是否计算每个字符取决于相关的p1,p2,p3值> = 0.05。
我尝试输入此代码以计算所有列中的唯一字符
b <- dat %>%
group_by(group) %>%
mutate(total = sum(n_distinct(t1[p1 >= 0.05], na.rm = TRUE),
n_distinct(t2[p2 >= 0.05], na.rm = TRUE),
n_distinct(t3[p3 >= 0.05], na.rm = TRUE)))
其结果是它计算t1,t2和t3的唯一字符,然后对其求和,得出以下“总”为6的数据集
dat <- data.frame(group = c(1,1,1,1,1), id = c(1,2,3,4,5),
t1 = c('a','a','b','b','c'),p1 = c(0.98,1,0.5,0.9,1),
t2 = c('b',NA,'a','c',NA),p2 = c(0.02,NA,0.25,0.10,NA),
t3 = c(NA,NA,'c',NA,NA),p3 = c(NA,NA,0.25,NA,NA),
total = c(6,6,6,6,6))
但是,我要做的是计算所有列中唯一字符的总数。换句话说,如果在t1列中看到“ a”,则不要在其他列(t2,t3)中计算“ a”。最终产品看起来像以下数据集,其中“ total”为3(表示a,b和c为存在的唯一字符)
dat <- data.frame(group = c(1,1,1,1,1), id = c(1,2,3,4,5),
t1 = c('a','a','b','b','c'),p1 = c(0.98,1,0.5,0.9,1),
t2 = c('b',NA,'a','c',NA),p2 = c(0.02,NA,0.25,0.10,NA),
t3 = c(NA,NA,'c',NA,NA),p3 = c(NA,NA,0.25,NA,NA),
total = c(3,3,3,3,3))
谢谢您的帮助
答案 0 :(得分:3)
我们可以使用map2
遍历每个对应的't'和'p'列,获取list
,filter
中基于“ p”列的值,pull
“ t”列的值,获取不同元素的数量(n_distinct
),并使用bind_cols
library(tidyverse)
map2_int(paste0('t', 1:3), paste0('p', 1:3), ~
dat %>%
select(.x, .y) %>%
filter_at(.y, all_vars(. >= 0.05)) %>%
pull(.x) %>%
n_distinct) %>%
bind_cols(dat, total = .)
,如果各列之间是“唯一的”,则不是每列获取n_distinct
,而是unlist
list
然后应用n_distinct
,然后使用mutate
map2(paste0('t', 1:3), paste0('p', 1:3), ~
dat %>%
select(.x, .y) %>%
filter_at(.y, all_vars(. >= 0.05)) %>%
pull(.x) ) %>%
unlist %>%
n_distinct %>%
mutate(dat, total = .)
# group id t1 p1 t2 p2 t3 p3 total
#1 1 1 a 0.98 b 0.02 <NA> NA 3
#2 1 2 a 1.00 <NA> NA <NA> NA 3
#3 1 3 b 0.50 a 0.25 c 0.25 3
#4 1 4 b 0.90 c 0.10 <NA> NA 3
#5 1 5 c 1.00 <NA> NA <NA> NA 3
如果我们进行group_by
n_distinct
,则可以通过在按“组”分组后summarise
将“ {total”的n_distinct
进行更改来更改以上内容
map2_df(paste0('t', 1:3), paste0('p', 1:3), ~
dat %>%
group_by(group) %>%
select(.x, .y) %>%
filter_at(.y, all_vars(. >= 0.05)) %>%
select(-.y) %>%
rename_at(.x, ~ 'total')) %>%
summarise(total = n_distinct(total)) %>%
left_join(dat)
答案 1 :(得分:3)
首先通过功能lapply
的{{1}}列进入p
,然后选择具有>= 0.05
的所有p
列的结果为true的行。一旦有了这些行,就可以使用Reduce('&'
选择要为其计算唯一性的数据,然后.SD[rows, paste0('t', 1:3)]
(将其强制为单个向量)进行计数,从而可以使用{{1} }直接计算不重复次数。
unlist
答案 2 :(得分:0)
这适用于任意数量的组和任意数量的列对。
dat %>%
gather(key, value, -group, -id) %>%
separate(key, c('key1', 'key2'), 1) %>%
group_by(group, id, key2) %>%
spread(key1, value) %>%
filter(p >= 0.05) %>%
pull(t) %>%
n_distinct() %>%
mutate(dat, total = .)