首页 > 解决方案 > 将数据从行移动到 R 中的列,忽略缺失值并根据转置列添加列

问题描述

我有一个实验数据集,参与者被分配到四种治疗中的一种。数据在数据集中的组织方式,每个处理都有一组单独的变量,因此对于每一行,一组列(对于他们看到的处理)具有有效值,其余三组列(对于三个他们没有看到的治疗)都是空的。

我想重新排列数据集,以便:

  1. 一个新列指定每个参与者被分配到哪种治疗(即哪一组列具有该行的有效值)

  2. 一组新的列报告参与者被分配到的治疗列的有效值

目前,我的数据集看起来像此代码生成的数据集:

T1a <- c(1, NA, NA, NA)
T1b <- c(2, NA, NA, NA)
T2a <- c(NA, NA, 3, NA)
T2b <- c(NA, NA, 4, NA)
T3a <- c(NA, 0, NA, NA)
T3b <- c(NA, 5, NA, NA)
T4a <- c(NA, NA, NA, 4)
T4b <- c(NA, NA, NA, 2)
data <- rbind(data.frame(T1a, T1b, T2a, T2b, T3a, T3b, T4a, T4b))

> data
  T1a T1b T2a T2b T3a T3b T4a T4b
1   1   2  NA  NA  NA  NA  NA  NA
2  NA  NA  NA  NA   0   5  NA  NA
3  NA  NA   3   4  NA  NA  NA  NA
4  NA  NA  NA  NA  NA  NA   4   2

我想重新排列数据集如下:

> data2
   Tr   a   b
1   1   1   2
2   3   0   5
3   2   3   4
4   4   4   2 

我知道我可以通过创建新列并为它们分配列的相应值来手动执行此操作,而不会丢失每行中的数据,但我想知道是否有更快、更优雅的方法来做到这一点。

非常感谢您的帮助!

标签: rdataframe

解决方案


使用dplyr和的解决方案tidyr

library(dplyr)
library(tidyr)

data2 <- data %>%
  gather(Column, Value) %>%
  drop_na(Value) %>%
  extract(Column, into = c("Letter", "Tr", "Subject"), regex = "(^T)([0-9]+)([a-z])+$") %>%
  spread(Subject, Value) %>%
  select(-Letter) %>%
  mutate(Tr = as.integer(Tr))
data2
#   Tr a b
# 1  1 1 2
# 2  2 3 4
# 3  3 0 5
# 4  4 4 2

推荐阅读