簡體   English   中英

R data.table如何基於另一列的值從多個列之一(按列NAME)獲取VALUE

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM