使用 tidyverse 方案按列值进行子集化和 row_binding
Subsetting and row_binding by column values using tidyverse scheme
我有一个 data.frame
,我想将其(按行)子集化为(重叠)"batches",然后 purrr:::map
将这些批处理为一个函数。在下面的示例中,d
是 data.frame
我想要子集和批处理:
set.seed(19)
n1 <- data.frame(c0= "N",c1 = rep("A",4),c2 = rep(c("i","j"),2), num = rnorm(4))
n2 <- data.frame(c0= "N", c1 = rep("B",6),c2 = rep(c("i","j"),3), num = rnorm(3))
y1 <- data.frame(c0 = "Y", c1 = rep("A",2),c2 = c("i","j"), num = rnorm(2))
y2 <- data.frame(c0 = "Y", c1 = rep("B",4),c2 = rep(c("i","j"),each = 2), num = rnorm(2))
d <- rbind(y1,y2,n1,n2)
这里是d
# c0 c1 c2 num
# 1 Y A i -0.7447795
# 2 Y A j -0.2597870
# 3 Y B i -0.1830838
# 4 Y B i 0.5186300
# 5 Y B j -0.1830838
# 6 Y B j 0.5186300
# 7 N A i -1.1894537
# 8 N A j 0.3885812
# 9 N A i -0.3443333
# 10 N A j -0.5478961
# 11 N B i 0.9806622
# 12 N B j -0.2366460
# 13 N B i 0.8097397
# 14 N B j 0.9806622
# 15 N B i -0.2366460
# 16 N B j 0.8097397
子集配方是
- 子集
c0
--> 给出组 Y
和 N
- 在
c0=="N"
子集内 c1
--> 给出组 NA
,NB
- 通过
c2
对 NA
和 NB
进行子集化 --> 给出组 NAi
、NAj
、NBi
、NBj
- row_bind
N?i
到 Y?i
和 N?j
到 Y?j
(其中 ?
是 A
或 B
) --> 给出最后的 4 个数据子集
在 R 中:
subset.Yi <- d %>% filter(c0=="Y"& c2=="i")
subset.Yj <- d %>% filter(c0=="Y"& c2=="j")
list(
d1 = d %>% filter(c0=="N" & c1 == "A", c2 == "i") %>% rbind(subset.Yi),
d2 = d %>% filter(c0=="N" & c1 == "B", c2 == "i") %>% rbind(subset.Yi),
d3 = d %>% filter(c0=="N" & c1 == "A", c2 == "j") %>% rbind(subset.Yj),
d4 = d %>% filter(c0=="N" & c1 == "B", c2 == "j") %>% rbind(subset.Yj)
) %>%
tibble::tibble(batches = paste0("batch",1:length(.)),data = .) ->tmp
如果 c2
的匹配不重要,我可以这样做:
d %>% filter(.,c0 == "N") %>%
group_by(.,c1) %>%
do(batches = rbind(d[d$c0=="Y"],.)) -> tmp
但这还不是全部。先感谢您!
顺便说一句,我知道在 tidyverse
之外这是可行的,但是当我为其余代码采用 tidyverse
方案时,我希望保持一致。
这里有一个适用于这种情况的解决方案(不过,很高兴看到其他人提供的其他可能更通用的方法)。
tmp <- d %>%
group_by(c2) %>%
nest(.key = c2) %>%
mutate(c2 = map(c2,~ .x %>%
filter(.,c0 == "N") %>%
group_by (.,c1) %>%
do(batches = bind_rows(
.x %>% filter(.,c0 == "Y") %>% select(-c1),
(.) %>% select(-c1) ))
))
tmp
这里将包含四个子集。然后我可以做类似
的事情
tmp %>% unnest(c2) %>% .$batches %>% map(.,~sum(.$num)) %>% unlist
它给出了 4 个子集中每个子集中的 colSum
列 num
。
[1] -1.94302047 1.14452254 -0.08355576 1.62951506
旁注:从技术上讲,在这里取消选择 c1
是没有必要的,但因为我是 row_binding,所以数据框的一部分忽略了值 c1
(参见上面的子集配方和注释?
), c1的值搞糊涂了,所以去掉了
我有一个 data.frame
,我想将其(按行)子集化为(重叠)"batches",然后 purrr:::map
将这些批处理为一个函数。在下面的示例中,d
是 data.frame
我想要子集和批处理:
set.seed(19)
n1 <- data.frame(c0= "N",c1 = rep("A",4),c2 = rep(c("i","j"),2), num = rnorm(4))
n2 <- data.frame(c0= "N", c1 = rep("B",6),c2 = rep(c("i","j"),3), num = rnorm(3))
y1 <- data.frame(c0 = "Y", c1 = rep("A",2),c2 = c("i","j"), num = rnorm(2))
y2 <- data.frame(c0 = "Y", c1 = rep("B",4),c2 = rep(c("i","j"),each = 2), num = rnorm(2))
d <- rbind(y1,y2,n1,n2)
这里是d
# c0 c1 c2 num
# 1 Y A i -0.7447795
# 2 Y A j -0.2597870
# 3 Y B i -0.1830838
# 4 Y B i 0.5186300
# 5 Y B j -0.1830838
# 6 Y B j 0.5186300
# 7 N A i -1.1894537
# 8 N A j 0.3885812
# 9 N A i -0.3443333
# 10 N A j -0.5478961
# 11 N B i 0.9806622
# 12 N B j -0.2366460
# 13 N B i 0.8097397
# 14 N B j 0.9806622
# 15 N B i -0.2366460
# 16 N B j 0.8097397
子集配方是
- 子集
c0
--> 给出组Y
和N
- 在
c0=="N"
子集内c1
--> 给出组NA
,NB
- 通过
c2
对NA
和NB
进行子集化 --> 给出组NAi
、NAj
、NBi
、NBj
- row_bind
N?i
到Y?i
和N?j
到Y?j
(其中?
是A
或B
) --> 给出最后的 4 个数据子集
在 R 中:
subset.Yi <- d %>% filter(c0=="Y"& c2=="i")
subset.Yj <- d %>% filter(c0=="Y"& c2=="j")
list(
d1 = d %>% filter(c0=="N" & c1 == "A", c2 == "i") %>% rbind(subset.Yi),
d2 = d %>% filter(c0=="N" & c1 == "B", c2 == "i") %>% rbind(subset.Yi),
d3 = d %>% filter(c0=="N" & c1 == "A", c2 == "j") %>% rbind(subset.Yj),
d4 = d %>% filter(c0=="N" & c1 == "B", c2 == "j") %>% rbind(subset.Yj)
) %>%
tibble::tibble(batches = paste0("batch",1:length(.)),data = .) ->tmp
如果 c2
的匹配不重要,我可以这样做:
d %>% filter(.,c0 == "N") %>%
group_by(.,c1) %>%
do(batches = rbind(d[d$c0=="Y"],.)) -> tmp
但这还不是全部。先感谢您!
顺便说一句,我知道在 tidyverse
之外这是可行的,但是当我为其余代码采用 tidyverse
方案时,我希望保持一致。
这里有一个适用于这种情况的解决方案(不过,很高兴看到其他人提供的其他可能更通用的方法)。
tmp <- d %>%
group_by(c2) %>%
nest(.key = c2) %>%
mutate(c2 = map(c2,~ .x %>%
filter(.,c0 == "N") %>%
group_by (.,c1) %>%
do(batches = bind_rows(
.x %>% filter(.,c0 == "Y") %>% select(-c1),
(.) %>% select(-c1) ))
))
tmp
这里将包含四个子集。然后我可以做类似
tmp %>% unnest(c2) %>% .$batches %>% map(.,~sum(.$num)) %>% unlist
它给出了 4 个子集中每个子集中的 colSum
列 num
。
[1] -1.94302047 1.14452254 -0.08355576 1.62951506
旁注:从技术上讲,在这里取消选择 c1
是没有必要的,但因为我是 row_binding,所以数据框的一部分忽略了值 c1
(参见上面的子集配方和注释?
), c1的值搞糊涂了,所以去掉了