Jestem bardzo nowy dla data.table
, ale chciałbym rozwiązać mój problem z nim, ponieważ mam wrażenie, że byłby 1000 razy szybszy niż w przypadku "zwykłych" danych .frames.Wypełnij tabelę danych w oparciu o wartość w innym data.table
Oto mój problem:
Co mam:
2 data.tables dt1
i dt2
tak:
dt1 <- data.table(SID=paste0("S", 1:15), Chromo=rep(1:3, e=5), PP=rep(1:5, 3), P1=0, P2=0, P3=0)
set.seed(17)
dt2 <- data.table(PID=rep(paste0("P", 1:3), c(2, 6, 3)), Chr=c(1, 3, 1, 1, 2, 3, 3, 3, 2, 2, 3), start= c(1, 1, 1, 4, 2, 1, 2, 4, 2, 4, 2), end=c(3, 4, 2, 5, 4, 1, 3, 5, 3, 5, 5), val=rnorm(11))
co chcę:
Wypełnij dt1
z dt2[, val]
w prawej kolumnie, na podstawie dt2[, PID]
i prawej linii, w oparciu o dt1[, Chromo]
= dt2[, Chr]
i dt1[, PP]
między dt2[, start]
i dt2[, end]
.
Co mam teraz zrobić:(co nie czyni mnie dumnym, co najmniej ...)
# preparing the tables, computing dt1 rows indices
dt2[, numcol:=(1:ncol(dt1))[match(dt2[,PID], colnames(dt1))]]
setkey(dt2, Chr, start, end)
setkey(dt1, Chromo, PP)
ind_start <- dt1[dt2[,.(Chr, start)], which=T]
ind_end <- dt1[dt2[,.(Chr, end)], which=T]
dt2[,c("ind_start", "ind_end"):=list(ind_start, ind_end)]
# and feeling I'm that close but can't conclude with `data.table` so doing this "lame" `for` loop with `data.frames`.......................
df1 <- as.data.frame(dt1)
df2 <- as.data.frame(dt2)
nr_seg <- nrow(df2)
for(i in 1:nr_seg){
df1[df2[i,"ind_start"]:df2[i,"ind_end"], df2[i,"numcol"]] <- df2[i, "val"]
}
Tabele wejściowe i sygnał wyjściowy (z wyjątkiem I d jak data.table
):
dt1
# SID Chromo PP P1 P2 P3
# 1: S1 1 1 0 0 0
# 2: S2 1 2 0 0 0
# 3: S3 1 3 0 0 0
# 4: S4 1 4 0 0 0
# 5: S5 1 5 0 0 0
# 6: S6 2 1 0 0 0
# 7: S7 2 2 0 0 0
# 8: S8 2 3 0 0 0
# 9: S9 2 4 0 0 0
# 10: S10 2 5 0 0 0
# 11: S11 3 1 0 0 0
# 12: S12 3 2 0 0 0
# 13: S13 3 3 0 0 0
# 14: S14 3 4 0 0 0
# 15: S15 3 5 0 0 0
dt2
# PID Chr start end val
# 1: P2 1 1 2 -0.23298702
# 2: P1 1 1 3 -1.01500872
# 3: P2 1 4 5 -0.81726793
# 4: P3 2 2 3 0.25523700
# 5: P2 2 2 4 0.77209084
# 6: P3 2 4 5 0.36658112
# 7: P2 3 1 1 -0.16561194
# 8: P1 3 1 4 -0.07963674
# 9: P2 3 2 3 0.97287443
# 10: P3 3 2 5 1.18078924
# 11: P2 3 4 5 1.71653398
df1
# SID Chromo PP P1 P2 P3
# 1 S1 1 1 -1.01500872 -0.2329870 0.0000000
# 2 S2 1 2 -1.01500872 -0.2329870 0.0000000
# 3 S3 1 3 -1.01500872 0.0000000 0.0000000
# 4 S4 1 4 0.00000000 -0.8172679 0.0000000
# 5 S5 1 5 0.00000000 -0.8172679 0.0000000
# 6 S6 2 1 0.00000000 0.0000000 0.0000000
# 7 S7 2 2 0.00000000 0.7720908 0.2552370
# 8 S8 2 3 0.00000000 0.7720908 0.2552370
# 9 S9 2 4 0.00000000 0.7720908 0.3665811
# 10 S10 2 5 0.00000000 0.0000000 0.3665811
# 11 S11 3 1 -0.07963674 -0.1656119 0.0000000
# 12 S12 3 2 -0.07963674 0.9728744 1.1807892
# 13 S13 3 3 -0.07963674 0.9728744 1.1807892
# 14 S14 3 4 -0.07963674 1.7165340 1.1807892
# 15 S15 3 5 0.00000000 1.7165340 1.1807892
Możesz użyć 'Foverlaps'. Jak decydujesz, w której kolumnie "Pi" muszą iść wartości? – Roland
@Roland, dziękuję, nie znam tej funkcji, przyjrzę się temu. Jeśli chodzi o 'Pi', kolumna' Pi' w 'PID' kolumny' dt2' musi pasować do nazwy kolumny w 'dt1' – Cath
Możesz znaleźć [** ten Q & A **] (http: // stackoverflow. com/questions/24480031/roll-join-with-start-end-window) przydatny punkt wyjścia. Wygląda na to, że twoja kolumna "PP" odpowiada kolumnie "pos" w tym poście. Uważam, że "zaktualizowana odpowiedź" autorstwa @Aruna jest bardzo przyjemna. – Henrik