从 data.frame 中的特定列返回值

Returning value from specific column in data.frame

我有一个 data.frame 的 14 列,由 13 个时间段的测试分数组成,全部为数字。最后一列,比如 X,表示每个学生(行)获得不及格成绩的具体时间点。我想创建一个单独的列,其中包含每个学生在特定失败时间点的失败考试成绩。

      dataframe<-data.frame(TestA=c(58,92,65,44,88), 
      TestB=c(17,22,58,46,98), 
      TestC=c(88,98,2,45,80), TestD=c(33,25,65,66,5), 
      TestE=c(98,100,100,100,100), X=c(2,2,3,NA,4))

以上是带有模拟数据的压缩版。第一个学生在第二个时间点不及格,依此类推,但第四个学生从未失败。结果列应该是 17,2 2, 2, NA, 5。我怎样才能做到这一点?

你可以试试

dataframe[cbind(1:nrow(dataframe), dataframe$X)]
#[1] 17 22  2 NA  5

来自?`[`

A third form of indexing is via a numeric matrix with the one column for each dimension: each row of the index matrix then selects a single element of the array, and the result is a vector. Negative indices are not allowed in the index matrix. NA and zero values are allowed: rows of an index matrix containing a zero are ignored, whereas rows containing an NA produce an NA in the result.

两种替代解决方案。

一个使用 purrr 包中的 map 函数

library(tidyverse)

dataframe %>%
  group_by(student_id = row_number()) %>%
  nest() %>%
  mutate(fail_score = map(data, ~c(.$TestA, .$TestB, .$TestC, .$TestD, .$TestE)[.$X])) %>%
  unnest()

# # A tibble: 5 x 8
#   student_id fail_score TestA TestB TestC TestD TestE     X
#        <int>      <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1          1         17    58    17    88    33    98     2
# 2          2         22    92    22    98    25   100     2
# 3          3          2    65    58     2    65   100     3
# 4          4         NA    44    46    45    66   100    NA
# 5          5          5    88    98    80     5   100     4

另一个使用rowwise

dataframe %>%
  rowwise() %>%
  mutate(fail_score = c(TestA, TestB, TestC, TestD, TestE)[X]) %>%
  ungroup()

# # A tibble: 5 x 7
#   TestA TestB TestC TestD TestE     X fail_score
#   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>      <dbl>
# 1    58    17    88    33    98     2         17
# 2    92    22    98    25   100     2         22
# 3    65    58     2    65   100     3          2
# 4    44    46    45    66   100    NA         NA
# 5    88    98    80     5   100     4          5

我将两者都发布是因为我觉得如果您有很多学生(即行)和测试(即列),map 方法会更快。