2017-01-19 15 views
0

我想计算一些非常简单的东西,但我找不到解决方案。我想切入一些数字,但我想保存垃圾箱。如何在不同的容器中切割一个数字并用新的容器扩展数据框?

bin.size = 100 
df = data.frame(x =c(300,400), 
       y = c("sca1","sca2")) 
cut(df$x, seq(0, 400, bin.size), 
    include.lowest = TRUE) 

给我

[1] (200,300] (300,400] 
Levels: [0,100] (100,200] (200,300] (300,400] 

但我想是这样的:

 bin y 
1 (0,100] sca1 
2 (100,200] sca1 
3 (200,300] sca1 
4 (0,100] sca2 
5 (100,200] sca2 
6 (200,300] sca2 
7 (300,400] sca2 

我想这样做,因为我想计算出在垃圾箱输入值的数量100.例如:

df2 = data.frame(snp = c(1,2,10,100,1,2,14,16,399), 
       sca = c("sca1","sca1","sca1","sca1","sca2","sca2","sca2","sca2","sca2")) 
df2 
    snp sca 
1 1 sca1 
2 2 sca1 
3 10 sca1 
4 100 sca1 
5 1 sca2 
6 2 sca2 
7 14 sca2 
8 16 sca2 
9 399 sca2 

snp可能是向量sca1中的位置。

的最终目标是要获得这样的:

 bin y num 
1 (0,100] sca1 4 
2 (100,200] sca1 0 
3 (200,300] sca1 0 
4 (0,100] sca2 4 
5 (100,200] sca2 0 
6 (200,300] sca2 0 
7 (300,400] sca2 1 

我能做的最好的是这样的:

df2$cat = cut(df2$snp, seq(0, 400, bin.size), 
include.lowest = TRUE) 
df2 
    snp sca  cat 
1 1 sca1 [0,100] 
2 2 sca1 [0,100] 
3 10 sca1 [0,100] 
4 100 sca1 [0,100] 
5 1 sca2 [0,100] 
6 2 sca2 [0,100] 
7 14 sca2 [0,100] 
8 16 sca2 [0,100] 
9 399 sca2 (300,400] 

或者这样:

table(df2$cat,df2$sca) 
      sca1 sca2 
    [0,100]  4 4 
    (100,200] 0 0 
    (200,300] 0 0 
    (300,400] 0 1 

但随着问题这最后一次尝试是(300,400]sca1没有意义,因为它确实不存在。它应该是NA或者不显示。如何解决这个问题?

+1

为什么不'(300,400]'意义鉴于输入'df2' ,'(100,200]'和'(200,300]'不应该出现在'sca1'? – thelatemail

+0

事实上,0和NA在我的分析中并不相同,所以我需要改变它。预计,我没有使用这些数据,这只是一个可重复的例子。 –

回答

2

下面是一个使用了几包从tidyverse一个办法:

library(dplyr) 
library(tidyr) 
library(purrr) 

df %>% 
    left_join(nest(df2, snp, .key = "snp"), by = c("y" = "sca")) %>% 
    mutate(
    cuts = map(x, ~ seq(0, ., by = 100)), 
    tbls = pmap(
     .l = list(snp, cuts), 
     .f = function(xx, breaks) { 
     z <- table(cut(xx$snp, breaks)) 
     data_frame(cut = names(z), count = z) 
     } 
    ) 
) %>% 
    select(y, tbls) %>% 
    unnest() 
#  y  cut count 
# 1 sca1 (0,100]  4 
# 2 sca1 (100,200]  0 
# 3 sca1 (200,300]  0 
# 4 sca2 (0,100]  4 
# 5 sca2 (100,200]  0 
# 6 sca2 (200,300]  0 
# 7 sca2 (300,400]  1 
+0

我很难理解什么是g在那里。如果我有这个数据集,而想计算r2的平均值而不是每个类别的snp数(count),我需要改变什么? 'df2 = data.frame(snp = c(1,2,10,100,1,2,14,16,399), r2 = c(0.7,0.8,0.7,0.1,0.9,0.98,0.8,0.8,0.01), (sca1,sca1,sca1,sca1,sca2,sca2,sca2,sca2,sca2,...))。谢谢!我认为这会更简单! –

+0

如果只用第一个'df2'运行代码的顶部两行(即'df%>%left_join(...)'),并与新的'df2'比较,则会看到变量' r2'是完全令人不安的分组。逐步浏览代码管道可以帮助您了解每一步发生的情况。如果'r2'与分箱有关,你需要解释它是如何有用的;如果不是,它可能需要被删除并在以后重新加入。 – r2evans

+0

这是我不明白的部分。因为我需要将结果加倍嵌套。如果我通过r2嵌套(df2,r2,.key =“r2”),我仍然需要通过snp嵌套(df2,snp,.key =“snp”)来嵌套,这将创建类别。如果我使用你发送的代码,并尝试将它嵌套在df2数据框中:'df%>%left_join(nest(df2,snp,.key =“snp”),by = c(“y”= “sca”))'它保持r2值分开。但我想同时计算平均值。所以我不知道如何筑巢两次...... –

2

在基础R:

data.frame(table(cat=cut(df2$snp, seq(0,400,100)),sca=df2$sca)) 

#  cat sca Freq 
#1 (0,100] sca1 4 
#2 (100,200] sca1 0 
#3 (200,300] sca1 0 
#4 (300,400] sca1 0 
#5 (0,100] sca2 4 
#6 (100,200] sca2 0 
#7 (200,300] sca2 0 
#8 (300,400] sca2 1 
相关问题