首页 文章

具有逻辑值矩阵的子集数据帧

提问于
浏览
4

Problem

我有四个人的数据,每个人都有四种不同的格式 . 措施是 xy ,个人是 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 的值 .

因此,在上面的示例中,行 1x 的最低值是针对个别 C . 因此,对于行 1 我想获得 y.C ,这是 39 .

在该示例中,结果向量应为 39, 63, 89, 81, 83 .

Approach

我试图通过首先为 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 的值 . 但我无法找到实现这一目标的方法 .

任何帮助深表感谢 . 建议采用完全不同的 - 更优雅的方法也非常受欢迎 .

非常感谢!

3 回答

  • 0

    我们使用以'x'('dx')和'y'('dy')开头的列对数据集进行子集化 . 使用带有行索引的 max.colcbind 获取'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"))
    
  • 1

    这是我的解决方案 . 核心思想是有一些函数 which.min, which.max 可以行应用于数据框:

    编辑:

    现在,我想为每一行获得具有最低x值的个体的y值 .

    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
    
  • 0

    我们可以创建如下函数,

    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
    

相关问题