2015-11-19 3 views
2

Вот частая проблема, с которой я столкнулся недавно в R с data.tableПереиндексирование в R с помощью data.table?

У меня есть таблица индексов, скажем DT1. Столбец x будет подмножеством индексов. Я бы работал с подтаблицей более крупного сырья, используя эти индексы. подтаблица обычно индексируется от 1 до N. (то есть столбец y)

тогда, например, я бы столкнулся с таблицей с парами индексов с исходной индексацией, и я хочу знать соответствующую новую индексацию.

Вот как это выглядит

DT1 <- data.table(x=c(0,3,5),y= c(11,22,33)) 
DT2 <- data.table(x=c(3,3,0,0,5),x=c(0,5,0,3,5)) 
# > DT1 
# x y 
# 1: 0 11 
# 2: 3 22 
# 3: 5 33 

# > DT2 
# x x 
# 1: 3 0 
# 2: 3 5 
# 3: 0 0 
# 4: 0 3 
# 5: 5 5 

Вот извилистый путь я нашел

cbind(DT1[DT2[,1,with=FALSE],on="x"][,2,with=FALSE],DT1[DT2[,2,with=FALSE],on="x"][,2,with=FALSE]) 
#  y y 
# 1: 22 11 
# 2: 22 33 
# 3: 11 11 
# 4: 11 22 
# 5: 33 33 

более основной способ сделать это с sapply дает тот же результат

tab=DT1$x 
lookup <- function(value){DT1$y[which(tab==value)]} 

colnames(DT2) <- c("x","xx") 

ans <- as.data.table(cbind(sapply(DT2$x,lookup),sapply(DT2$xx,lookup))) 
colnames(ans) <- c("y","y") 

Однако первое решение выглядит немного уродливо для меня

Мне не нравится второй, потому что мне нужно определить назначение значения для вкладок каждый раз, когда я использую поиск функции в lapply. Если бы мне пришлось искать в разных таблицах, у меня был бы выбор либо создать новую функцию поиска, специфичную для этой таблицы, либо сохранить в памяти вкладку переменных (temp). возможно есть способ сделать lapply с функцией двух переменных lookup <-function (tab,value) {...}? что я не знаю

Я уверен, что существует много других способов. Я не уверен, что я делаю именно с первым решением. в основном синтаксис в data.table связан с (внутренним и внешним) JOINS. но в конечном выпуске я хочу сохранить исходный порядок таблицы DT2. установив столбец x в качестве ключа для DT2, будет сортировать этот столбец, создавая такие вещи, как merge, которые не адаптированы к этому?

Я желаю услышать от вас, что является лучшей реализацией, - я уверен, что есть много лучших, - а также, что наиболее эффективно при работе с очень большими таблицами.

+1

'DT2 [, lapply (.SD, function (x) factor (x, levels = DT1 $ x, labels = DT1 $ y))]'? – A5C1D2H2I1M1N2O1R2T1

+0

отлично, спасибо! что означает .SD? –

+1

@AnandaMahto - очень аккуратный код, хотя это использует синтаксис 'data.frame' в частях. Но я не уверен в этом. – thelatemail

ответ

7

идиоматические data.table подход будет обновлениеDT2, а присоединения следующим образом:

require(data.table) # v1.9.6 
setnames(DT2, c("a", "b")) # no duplicate names!! 
for (nm in names(DT2)) { 
    DT2[DT1, paste0(nm, ".val") := y, on = structure("x", names=nm)] 
} 
DT2[] 
# a b a.val b.val 
# 1: 3 0 22 11 
# 2: 3 5 22 33 
# 3: 0 0 11 11 
# 4: 0 3 11 22 
# 5: 5 5 33 33 

Вы можете скрыть цикл с помощью lapply() возможно.Если DT2 был вместо следующим образом (в длинной форме, см DT3):

DT3 = melt(DT2, measure = c("a", "b"), variable.name = "id", value.name = "x.val") 

, то вы можете сделать:

DT3[DT1, y.val := y, on = c(x.val = "x")] 

Вы можете использовать y.val := i.y быть более явным, что вы имеете в виду y столбец из таблицы данных. соответствует аргументу i .. (полезно, когда оба они имеют общие имена столбцов).

+0

есть ли способ избежать цикла for? –

+2

Не так, как вы структурируете свой DT2. Что случилось с петлей? – Arun

+1

Отредактировано, чтобы показать, как 'DT2' должен быть таким, чтобы сделать это с одним соединением. – Arun

1

Вы можете попробовать что-то вроде следующего:

DT2[, lapply(.SD, function(x) DT1[["y"]][match(x, DT1[["x"]])])] 
#  x x 
# 1: 22 11 
# 2: 22 33 
# 3: 11 11 
# 4: 11 22 
# 5: 33 33 
str(.Last.value) 
# Classes ‘data.table’ and 'data.frame': 5 obs. of 2 variables: 
# $ x: num 22 22 11 11 33 
# $ x: num 11 33 11 22 33 
# - attr(*, ".internal.selfref")=<externalptr> 
+0

спасибо всем, много полезных ответов .... на самом деле так много ответов сейчас я не знаю, какой из них выбрать на практике ... –

Смежные вопросы