从data.frame

时间:2018-06-12 13:45:29

标签: r function conditional

我有14个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。如何实现此目的?

2 个答案:

答案 0 :(得分:3)

你可以尝试

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

来自?`[`

  

第三种索引形式是通过数字矩阵,每个维度都有一列:索引矩阵的每一行然后选择数组的单个元素,结果是一个向量。索引矩阵中不允许使用负指数。允许使用NA和零值:忽略包含零的索引矩阵的行,而包含NA的行在结果中生成NA。

答案 1 :(得分:0)

两种替代解决方案。

一个使用map

中的purrr函数
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方法会更快。