2017-01-19 7 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

Почему не '(300400]' имеет смысл Учитывая ввод '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 для каждой категории (количество), что мне нужно изменить? '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), sca = c («sca1», «sca1», «sca1», «sca1», «sca2», «sca2», «sca2», «sca2», «sca2»)). Благодаря! Я думал, что это будет проще! –

+0

, если вы запустили только две верхние строки кода (т. Е. 'Df%>% left_join (...)') с первым 'df2' и сравните с вашим новым' df2', вы увидите, что переменная ' r2' полностью нарушает группировку. Пройти через конвейер кода, как это полезно, чтобы увидеть, что происходит на каждом шаге. Если 'r2' относится к биннингам, вам нужно объяснить, как это полезно; если нет, его, возможно, нужно будет удалить и повторно подключить позже. – r2evans

+0

Это часть, которую я не понимаю. Потому что мне нужно будет удвоить результаты поиска. Если я гнезюсь через r2 'nest (df2, r2, .key =" r2 ")' мне все равно нужно вложить snp 'nest (df2, snp, .key =" snp ")', который будет создавать категории. Если я использую отправленный код и пытаюсь вложить его с добавлением в фрейм данных df2: 'df%>% left_join (гнездо (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