![](/img/trans.png)
[英]Creating a function that calls a column both using a string and as a variable - use of base R and dplyr
[英]Use string to select column per row in dplyr (or base R)
我有一個填充其他列名稱的列。 我想獲取每個列名稱中的值。
# three columns with values and one "key" column
library(dplyr)
data = data.frame(
x = runif(10),
y = runif(10),
z = runif(10),
key = sample(c('x', 'y', 'z'), 10, replace=TRUE)
)
# now get the value named in 'key'
data = data %>% mutate(value = VALUE_AT_COLUMN(key))
我很確定答案與mutate的懶惰eval版本有關,但我不能為我的生活弄明白。
任何幫助,將不勝感激。
我們可以試試data.table
。 將'data.frame'轉換為'data.table'( setDT(data)
),按行序列分組,我們使用.SD
對'key'指定的列進行子集化。
library(data.table)
setDT(data)[, .SD[, key[[1L]], with=FALSE] ,1:nrow(data)]
或者,在按行序列分組后,將'key'轉換為character
類(因為它factor
)后get
另一個選項,如前一種情況。
setDT(data)[, get(as.character(key)), 1:nrow(data)]
這是do
一個選項
library(dplyr)
data %>%
group_by(rn = row_number()) %>%
do(data.frame(., value= .[[.$key]]))
這是一個Base R解決方案:
data$value = diag(as.matrix(data[,data$key]))
對於內存高效且快速的解決方案,您應該通過執行連接來更新原始data.table,如下所示:
data[.(key2 = unique(key)), val := get(key2), on=c(key="key2"), by=.EACHI][]
對於每個key2
,計算data$key
中的匹配行。 這些行使用key2
包含的列中的值進行更新。 例如, key2="x"
與行1,2,6,8,10
匹配。 data$x
的相應值是data$x[c(1,2,6,8,10)]
。 by=.EACHI
確保表達get(key2)
針對的每個值執行key2
。
由於此操作僅在唯一值上執行,因此應比在行中執行操作快得多。 由於data.table是通過引用更新的,因此它應該具有很高的內存效率(這也有助於提高速度)。
這肯定感覺應該有一個基本的R解決方案,但我能做的最好的是tidyr
,首先將數據轉換為寬格式,然后過濾那些匹配所需鍵的觀察。
data %>%
add_rownames("index") %>%
gather(var, value, -index, -key) %>%
filter(key == var)
基本的R解決方案幾乎可以工作:
data[cbind(seq_along(data$key), data$key)]
對於給出的數據,它確實有效,但因為它使用矩陣,所以它有兩個嚴重的問題。 一個因素的順序很重要,因為它只是強迫它,並按因子級別而不是列名稱選擇列。 另一個是結果輸出是一個character
,而不是numeric
,因為在轉換為矩陣時,由於key
列而選擇了類型character
。 關鍵問題是沒有data.frame
類似於矩陣行為
通過'['單個參數'i'索引數組時,可以是一個矩陣,其列數與'x'的維數相同; 結果是一個向量,其元素對應於'i'每行中的索引集。
鑒於這些問題,我可能會采用tidyr
解決方案,因為列可變地可選,這意味着它們可能代表同一可觀察單元的不同觀察結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.