具有逻辑值矩阵的子集数据框
Subset data frame with matrix of logical values
问题
我有四个人的两项措施的数据,每个人都采用宽格式。度量是 x
和 y
,个体是 A, B, C, D
。数据框看起来像这样
d <- data.frame(matrix(sample(1:100, 40, replace = F), ncol = 8))
colnames(d) <- paste(rep(c("x.", "y."),each = 4), rep(LETTERS[1:4], 2), sep ="")
d
x.A x.B x.C x.D y.A y.B y.C y.D
1 56 65 42 96 100 76 39 26
2 19 93 94 75 63 78 5 44
3 22 57 15 62 2 29 89 79
4 49 13 95 97 85 81 60 37
5 45 38 24 91 23 82 83 72
现在,我想为每一行获取具有最低值 x
的个体的 y
值。
所以在上面的例子中,行 1
中 x
的最低值是针对个人 C
的。因此,对于 1
行,我想获得 y.C
即 39
.
在示例中,生成的向量应为 39, 63, 89, 81, 83
。
接近
我试图通过首先为 x
的值生成 d
的子集矩阵来实现这一点。
t(apply(d[,1:4], 1, function(x) min(x) == x))
x.A x.B x.C x.D
[1,] FALSE FALSE TRUE FALSE
[2,] TRUE FALSE FALSE FALSE
[3,] FALSE FALSE TRUE FALSE
[4,] FALSE TRUE FALSE FALSE
[5,] FALSE FALSE TRUE FALSE
现在我想应用这个矩阵来为 y
的值对数据框的子集进行子集化。但我找不到实现此目标的方法。
非常感谢任何帮助。也非常欢迎提出完全不同 - 更优雅 - 方法的建议。
非常感谢!
我们使用以 'x' ('dx') 和 'y' ('dy') 开头的列对数据集进行子集化。使用max.col
、cbind
和行索引得到'dx'每一行中最小值的列索引,得到'dy'.
中对应的元素
dx <- d[grep('^x', names(d))]
dy <- d[grep('^y', names(d))]
dy[cbind(1:nrow(dx),max.col(-dx, 'first'))]
#[1] 39 63 89 81 83
以上可以很容易地转换为函数
get_min <- function(dat){
dx <- dat[grep('^x', names(dat))]
dy <- dat[grep('^y', names(dat))]
dy[cbind(1:nrow(dx), max.col(-dx, 'first'))]
}
get_min(d)
#[1] 39 63 89 81 83
或使用 OP 基于 apply
的方法
t(d[,5:8])[apply(d[,1:4], 1, function(x) min(x) == x)]
#[1] 39 63 89 81 83
数据
d <- structure(list(x.A = c(56L, 19L, 22L, 49L, 45L),
x.B = c(65L,
93L, 57L, 13L, 38L), x.C = c(42L, 94L, 15L, 95L, 24L),
x.D = c(96L,
75L, 62L, 97L, 91L), y.A = c(100L, 63L, 2L, 85L, 23L),
y.B = c(76L,
78L, 29L, 81L, 82L), y.C = c(39L, 5L, 89L, 60L, 83L),
y.D = c(26L,
44L, 79L, 37L, 72L)), .Names = c("x.A", "x.B", "x.C",
"x.D",
"y.A", "y.B", "y.C", "y.D"), class = "data.frame",
row.names = c("1", "2", "3", "4", "5"))
这是我的解决方案。核心思想是有函数which.min, which.max
可以行应用于数据框:
编辑:
Now, would I would like to obtain for each row is the value of y for
the individual with the lowest value of x.
ind <- apply(d[ ,1:4], 1, which.min) # build column index by row
res <- d[,5:8][cbind(1:nrow(d), ind)] # rows are in order, select values by matrix
names(res) <- colnames(d)[5:8][ind] # set colnames as names from the sample column
res
y.D y.B y.D y.A y.D
18 46 16 85 80
警告:仅当个人在治疗 x 的顺序相同时才有效。和y。和所有在场的人。否则,您可以像 Akrun 的解决方案中那样使用 grep。
# My d was:
x.A x.B x.C x.D y.A y.B y.C y.D
1 88 96 65 55 14 99 63 18
2 12 11 27 45 70 46 20 69
3 32 81 21 9 77 44 91 16
4 8 84 42 78 85 94 28 90
5 31 51 83 2 67 25 54 80
我们可以创建一个函数如下,
get_min <- function(x){
d1 <- x[,1:4]
d2 <- x[,5:8]
mtrx <- as.matrix(d2[,apply(d1, 1, which.min)])
a <- row(mtrx) - col(mtrx)
split(mtrx, a)$"0"
}
get_min(d)
#[1] 39 63 89 81 83
问题
我有四个人的两项措施的数据,每个人都采用宽格式。度量是 x
和 y
,个体是 A, B, C, D
。数据框看起来像这样
d <- data.frame(matrix(sample(1:100, 40, replace = F), ncol = 8))
colnames(d) <- paste(rep(c("x.", "y."),each = 4), rep(LETTERS[1:4], 2), sep ="")
d
x.A x.B x.C x.D y.A y.B y.C y.D
1 56 65 42 96 100 76 39 26
2 19 93 94 75 63 78 5 44
3 22 57 15 62 2 29 89 79
4 49 13 95 97 85 81 60 37
5 45 38 24 91 23 82 83 72
现在,我想为每一行获取具有最低值 x
的个体的 y
值。
所以在上面的例子中,行 1
中 x
的最低值是针对个人 C
的。因此,对于 1
行,我想获得 y.C
即 39
.
在示例中,生成的向量应为 39, 63, 89, 81, 83
。
接近
我试图通过首先为 x
的值生成 d
的子集矩阵来实现这一点。
t(apply(d[,1:4], 1, function(x) min(x) == x))
x.A x.B x.C x.D
[1,] FALSE FALSE TRUE FALSE
[2,] TRUE FALSE FALSE FALSE
[3,] FALSE FALSE TRUE FALSE
[4,] FALSE TRUE FALSE FALSE
[5,] FALSE FALSE TRUE FALSE
现在我想应用这个矩阵来为 y
的值对数据框的子集进行子集化。但我找不到实现此目标的方法。
非常感谢任何帮助。也非常欢迎提出完全不同 - 更优雅 - 方法的建议。
非常感谢!
我们使用以 'x' ('dx') 和 'y' ('dy') 开头的列对数据集进行子集化。使用max.col
、cbind
和行索引得到'dx'每一行中最小值的列索引,得到'dy'.
dx <- d[grep('^x', names(d))]
dy <- d[grep('^y', names(d))]
dy[cbind(1:nrow(dx),max.col(-dx, 'first'))]
#[1] 39 63 89 81 83
以上可以很容易地转换为函数
get_min <- function(dat){
dx <- dat[grep('^x', names(dat))]
dy <- dat[grep('^y', names(dat))]
dy[cbind(1:nrow(dx), max.col(-dx, 'first'))]
}
get_min(d)
#[1] 39 63 89 81 83
或使用 OP 基于 apply
的方法
t(d[,5:8])[apply(d[,1:4], 1, function(x) min(x) == x)]
#[1] 39 63 89 81 83
数据
d <- structure(list(x.A = c(56L, 19L, 22L, 49L, 45L),
x.B = c(65L,
93L, 57L, 13L, 38L), x.C = c(42L, 94L, 15L, 95L, 24L),
x.D = c(96L,
75L, 62L, 97L, 91L), y.A = c(100L, 63L, 2L, 85L, 23L),
y.B = c(76L,
78L, 29L, 81L, 82L), y.C = c(39L, 5L, 89L, 60L, 83L),
y.D = c(26L,
44L, 79L, 37L, 72L)), .Names = c("x.A", "x.B", "x.C",
"x.D",
"y.A", "y.B", "y.C", "y.D"), class = "data.frame",
row.names = c("1", "2", "3", "4", "5"))
这是我的解决方案。核心思想是有函数which.min, which.max
可以行应用于数据框:
编辑:
Now, would I would like to obtain for each row is the value of y for the individual with the lowest value of x.
ind <- apply(d[ ,1:4], 1, which.min) # build column index by row
res <- d[,5:8][cbind(1:nrow(d), ind)] # rows are in order, select values by matrix
names(res) <- colnames(d)[5:8][ind] # set colnames as names from the sample column
res
y.D y.B y.D y.A y.D
18 46 16 85 80
警告:仅当个人在治疗 x 的顺序相同时才有效。和y。和所有在场的人。否则,您可以像 Akrun 的解决方案中那样使用 grep。
# My d was:
x.A x.B x.C x.D y.A y.B y.C y.D
1 88 96 65 55 14 99 63 18
2 12 11 27 45 70 46 20 69
3 32 81 21 9 77 44 91 16
4 8 84 42 78 85 94 28 90
5 31 51 83 2 67 25 54 80
我们可以创建一个函数如下,
get_min <- function(x){
d1 <- x[,1:4]
d2 <- x[,5:8]
mtrx <- as.matrix(d2[,apply(d1, 1, which.min)])
a <- row(mtrx) - col(mtrx)
split(mtrx, a)$"0"
}
get_min(d)
#[1] 39 63 89 81 83