我会选择 sapply:
data <- read.table(text="Which Test?|Test1 |Test2 |Test3 |RESULT
Test1 |TRUE |80% |0 |
Test2 |FALSE |25% |0 |
Test1 |TRUE |16% |0 |
Test3 |FALSE |12% |1 |",
header=T,
sep="|",
stringsAsFactors=F,
strip.white=T)
data$RESULT <- sapply( 1:nrow(data), function(x) { data[x,data[x,1]] })
对于每一行,获取目标列data[x,1]
(内部访问),并为此列获取行值data[x,...]
.
Output:
> data
Which.Test. Test1 Test2 Test3 RESULT Result
1 Test1 TRUE 80% 0 NA TRUE
2 Test2 FALSE 25% 0 NA 25%
3 Test1 TRUE 16% 0 NA TRUE
4 Test3 FALSE 12% 1 NA 1
有两个变量的函数sapply
将会:
function(x) {
tcol <- data[x,1] # First column value of row x
data[x,tcol]) # Get the value at row x and column tcol
}
一种方法使用Map/mapply
将提供 'i' (seq(nrow(data))
), 'j' (match(data$Which.Test., names(data))
) 行/列索引及使用[
从“数据”中提取元素。我们用list
以便“数据”保留为单个数据帧,并将循环使用“i”、“j”的长度。
mapply(`[`, list(data), seq(nrow(data)), match(data$Which.Test., names(data) ) )
#[1] "TRUE" "25%" "TRUE" "1"
不过,可能的矢量化方法只是
data[cbind(1:nrow(data), match(data$Which.Test., names(data)))]
## [1] " TRUE" "25%" " TRUE" "1"
这与中的值匹配Which.Test.
针对的列名data
并返回匹配列的索引。然后,我们通过将每行的这些列与1:nrow(data)
using cbind
.
上面@DavidArenburg解决方案的更详细解释(因为我不得不花一些时间来完全理解它):
子集运算符接受一个矩阵,所以我们这样做:
-
1:nrow(data)
很容易给出一个向量[1] 1 2 3 4
对应于我们数据集中的行数
-
match(data$Which.Test., names(data)))
给出每个匹配测试的索引[1] 1 2 3 4
-
cbind(..,..)
绑定我们前面的两个点来构建一个矩阵:
[,1] [,2]
[1,] 1 2
[2,] 2 3
[3,] 3 2
[4,] 4 4
我们看到这个矩阵与我们希望取值的每一行相匹配。因此,当将此矩阵作为数据集的选择器时,我们会得到正确的结果。然后我们可以将它分配给一个新变量或 df 的新列。