При оценке полезности data.table
(против dplyr
) решающим фактором является возможность использовать его в рамках функций и циклов.
Для этого я изменил фрагмент кода, используемый в этом сообщении: data.table vs dplyr: can one do something well the other can't or does poorly?, так что вместо жестко закодированных имен переменных набора данных («вырезать» и «ценовые» переменные набора данных «бриллианты»), он становится агрегированным по дате - cut-n-paste готова для использования внутри любой функции или цикла (если мы не знаем названия столбцов заранее).Как использовать data.table внутри функций и циклов?
Это исходный код:
library(data.table)
dt <- data.table(ggplot2::diamonds)
dt[cut != "Fair", .(mean(price),.N), by = cut]
Это его набор данных агностик эквивалент:
dt <- data.table(diamonds)
nVarGroup <- 2 #"cut"
nVarMeans <- 7 #"price"
strGroupConditions <- levels(dt[[nVarGroup]])[-1] # "Good" "Very Good" "Premium" "Ideal"
strVarGroup <- names(dt)[nVarGroup]
strVarMeans <- names(dt)[nVarMeans]
qAction <- quote(mean(get(strVarMeans))) #! w/o get() it does not work!
qGroup <- quote(get(strVarGroup) %in% strGroupConditions) #! w/o get() it does not work!
dt[eval(qGroup), .(eval(qAction), .N), by = strVarGroup]
Примечание (Спасибо ответить ниже): если вам нужно изменить значение переменной по ссылке, вам нужно использовать ()
, не get()
, как показано ниже:
strVarToBeReplaced <- names(dt)[1]
dt[eval(qGroup), (strVarToBeReplaced) := eval(qAction), by = strGroup][]
Теперь вы можете вырезать-н-вставить следующий код для всех ваших потребностей зацикливания:
for(nVarGroup in 2:4) # Grouped by several categorical values...
for(nVarMeans in 5:10) { # ... get means of all numerical parameters
strGroupConditions <- levels(dt[[nVarGroup]])[-1]
strVarGroup <- names(dt)[nVarGroup]
strVarMeans <- names(dt)[nVarMeans]
qAction <- quote(mean(get(strVarMeans)))
qGroup <- quote(get(strVarGroup) %in% strGroupConditions)
p <- dt[eval(qGroup), .(AVE=eval(qAction), COUNT=.N), by = strVarGroup]
print(sprintf("nVaGroup=%s, nVarMeans=%s: ", strVarGroup, strVarMeans))
print(p)
}
Мой первый вопрос:
Код выше, позволяя требуемые функциональные/циклических потребностей, представляется весьма запутанным. - Он использует различные множественные (возможно, непротиворечивые) неинтуитивные трюки, такие комбинации ()
, get()
, quote()
/eval()
, [[]]
). Кажется, слишком много для такой простой потребности ...
Есть ли еще один лучший способ доступа и изменения значений data.tables в циклах? Возможно, с on=
, lapply
/.SD
/.SDcols
?
Пожалуйста, поделитесь своими идеями ниже. Это обсуждение предназначено для дополнения и консолидации связанных бит с других должностей (например, перечисленных здесь: How can one work fully generically in data.table in R with column names in variables). В конце концов, было бы здорово создать специальную виньетку для использования data.table
в пределах functions
и loops
.
Второй вопрос:
Это dplyr проще для этой цели? - Для этого вопроса, однако, я установил отдельный пост: Is dplyr easier than data.table to be used within functions and loops?.
Если вы хотите отказаться от обмана или плохих имен столбцов и/или очистить их сначала, я думаю, это проще. – Frank
предложение: было бы лучше разместить новый qn, чем изменить предыдущий qn, потому что новый не будет получать большую видимость.try 'dt [eval (qGroup), (strVarToBeReplaced): = 999, by = strGroup] []' вместо – chinsoon12
У меня нет вашего вопроса. Как ваш код «набор данных-агностик» более общий, чем просто использование data.table напрямую? – Hugh