[英]R data.table How to obtain the VALUE from one of many columns (by column NAME), based on the value of another column
我試圖通過引用列名稱從R中的data.table中提取特定值
require(data.table)
# Create data.frame
cohort = c("cohort1", "cohort2", "cohort3")
year = c(2019, 2018, 2020)
item_2018 = c("alpha", "beta", "gamma")
item_2019 = c("banana", "apples", "oranges")
item_2020 = c("Tim", "Daniel","Simon")
desired_result = c("banana", "beta", "Simon") # the values in this column I want to programatically grab from the relevant column before
cohorts <- data.frame(cohort,year, item_2018, item_2019, item_2020, desired_result)
setDT(cohorts) # turn the data.frame into a data.table
setkey(cohorts, year) # setting the key for the data.table (not sure if this is necessary)
# CALCULATE NEW FIELD (attempts - not working)
# trying to populate new column "result_attempt_1" with : c("banana", "beta", "Simon")
cohorts[, result_attempt_1 := get(paste0("item_", year)), by = year] # this returns c("Simon", "Simon", "Simon") rather than c("banana", "beta", "Simon")
cohorts[, result_attempt_2 := .SD[, get(paste0("item_", year)), by = year]] # very wrong
cohorts[, result_attempt_3 := .SD[, get(paste0("item_", year)), by = get(paste0("item_", year))]] # very wrong
我希望“ desired_results”列中的值最終出現在“ result_attempt”列中。 我得到的最接近的是針對每個記錄/行重復的最后一個正確結果。
任何想法如何實現這一目標? 非常感謝。
一種選擇是行/列索引
cohorts[, result := as.data.frame(.SD)[cbind(seq_len(.N),
match(year, sub("item_", "", names(.SD))))], .SDcols = 3:5]
cohorts
# cohort year item_2018 item_2019 item_2020 desired_result result
#1: cohort2 2018 beta apples Daniel beta beta
#2: cohort1 2019 alpha banana Tim banana banana
#3: cohort3 2020 gamma oranges Simon Simon Simon
這是一個東西:
for (rw in seq_len(nrow(cohorts))) {
set(
cohorts,
i = rw,
j = "newcol",
value = cohorts[[paste0("item_", cohorts[["year"]][rw])]][rw]
)
}
> cohorts
cohort year item_2018 item_2019 item_2020 desired_result newcol
1: cohort2 2018 beta apples Daniel beta beta
2: cohort1 2019 alpha banana Tim banana banana
3: cohort3 2020 gamma oranges Simon Simon Simon
使用data.table::melt
另一個選項,匹配item_year然后查找並通過引用更新:
cohorts[
melt(cohorts, measure.vars=patterns("^item"), variable.factor=FALSE)[,
value[variable==paste0("item_", year)], by=.(cohort)],
on=.(cohort), desired_result := V1]
非常感謝您的幫助。
看來我面臨的根本問題是data.table中列的數據類型。
似乎“ item_xxxx”列被強制為“因素”而不是“字符”。
如果我們從頭開始定義data.table(而不是通過data.frame階段),那么我最初提供的代碼確實可以正常工作。
require(data.table)
# Create data.table
cohort = c("cohort1", "cohort2", "cohort3")
year = c(2019, 2018, 2020)
item_2018 = c("alpha", "beta", "gamma")
item_2019 = c("banana", "apples", "oranges")
item_2020 = c("Tim", "Daniel","Simon")
desired_result = c("banana", "beta", "Simon") # the values in this column I want to programatically grab from the relevant column before
# create DATA.TABLE (not data.frame)
cohorts <- data.table(cohort,year, item_2018, item_2019, item_2020, desired_result)
str(cohorts)
# setDT(cohorts)
# trying to populate new column "result_attempt_1" with : c("banana", "beta", "Simon")
cohorts[, result_attempt_1 := get(paste0("item_", year)), by = year] # this now returns c("banana", "beta", "Simon"), as desired
cohorts
所以-在這里帶回家消息-如果不起作用,請運行str(data_name)來檢查列數據類型。
謝謝大家的幫助和支持。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.