如果我的問題的表達令人困惑,我深表歉意,我無法找到類似的線索來澄清我的問題的英語。
我正在處理一個類似于下圖的資料樣本:
| 標簽 1 | 標簽2 | 標簽 3 | 標簽# |
|---|---|---|---|
| 值1 | 值4 | 值7 | 標簽2 |
| 值2 | 值5 | 值8 | 標簽 1 |
| 值3 | 值6 | 值9 | 標簽 3 |
我正在嘗試創建一個新列“currentvalue”,它讀取特定行中 label# 的值,然后對于該行,使用 label# 中命名的任何列的該行值填充該列。換句話說,我希望我的輸出看起來像這樣:
| 標簽 1 | 標簽2 | 標簽 3 | 標簽# | 當前值 |
|---|---|---|---|---|
| 值1 | 值4 | 值7 | 標簽2 | 值4 |
| 值2 | 值5 | 值8 | 標簽 1 | 值2 |
| 值3 | 值6 | 值9 | 標簽 3 | 值9 |
我能想到的唯一解決方案涉及多個 for 回圈,我認為這在計算上非常低效。我一直在尋找可以幫助我為此撰寫矢量化解決方案的執行緒的堆疊溢位,但我認為我無法很好地闡明問題,因為我的搜索都沒有幫助。感謝任何幫助(包括幫助更好地說明我的問題)。
uj5u.com熱心網友回復:
使用dplyr和的解決方案purrr。imap_chr可以有效地通過每一行應用一個函式。第一個引數是 中的內容label#,而第二個引數是行號。
通常rowwise當資料幀很大時操作會很慢,所以盡量避免rowwise并盡可能使用替代方法。
library(dplyr)
library(purrr)
dat2 <- dat %>%
mutate(currentvalue = imap_chr(`label#`, ~dat[.y, .x]))
dat2
# label1 label2 label3 label# currentvalue
# 1 value1 value4 value7 label2 value4
# 2 value2 value5 value8 label1 value2
# 3 value3 value6 value9 label3 value9
資料
dat <- read.table(text = "label1 label2 label3 label
value1 value4 value7 label2
value2 value5 value8 label1
value3 value6 value9 label3", header = TRUE) %>%
setnames(c("label1", "label2", "label3", "label#"))
uj5u.com熱心網友回復:
有點亂,我認為可能有更好的方法,但您可以嘗試
library(dplyr)
library(tibble)
df <- read.table(text = "label1 label2 label3 label#
value1 value4 value7 label2
value2 value5 value8 label1
value3 value6 value9 label3", h = T)
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == label)]])
row label1 label2 label3 label currentvalue
<chr> <chr> <chr> <chr> <chr> <chr>
1 1 value1 value4 value7 label2 value4
2 2 value2 value5 value8 label1 value2
3 3 value3 value6 value9 label3 value9
當我用 讀取你的資料時read.table,label#變成label.
列名 label#
names(df)[4] <- "label#"
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == 'label#')]])
row label1 label2 label3 `label#` currentvalue
<chr> <chr> <chr> <chr> <chr> <chr>
1 1 value1 value4 value7 label2 label2
2 2 value2 value5 value8 label1 label1
3 3 value3 value6 value9 label3 label3
使用基礎 R
x <- match(df$label, names(df))
y <- 1:nrow(df)
z <- data.frame(y, x)
df$currentvalue <- apply(z,1, function(x) df[x[1],x[2]])
時間檢查
microbenchmark::microbenchmark(
a = {
df %>%
rowwise %>%
rownames_to_column(., "row") %>%
mutate(currentvalue = .[[which(rownames(.) == row),which(names(.) == label)]])
},
b = {
x <- match(df$label, names(df))
y <- 1:nrow(df)
z <- data.frame(y, x)
df$currentvalue <- apply(z,1, function(x) df[x[1],x[2]])
}
)
Unit: microseconds
expr min lq mean median uq max neval cld
a 6157.8 6861.95 8773.098 7465.75 9367.1 26232.8 100 b
b 360.6 399.75 692.073 488.40 666.9 4225.0 100 a
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/381294.html
