如何将成对的列移动到行中并同时创建一个 ID?

How can I move pairs of columns into rows and create an ID at the same time?

我有一堆原始数据是从一个优化选项不多的软件中获得的。 当我将它转换为 csv 并读入 R 时,我得到这个:

如您所见,我有 2 种类型的变量,ForceTime,用于 15 个不同的数据包。我想将 Force 和 Time 的所有数据分组为仅 2 列,并使用每个数据集的 ID 创建第三列,如下所示:

ID                     | Force| Time
------------------------------------
SR_1.5x1.5x1.5_90s 001 | 52.2 | 0.00
SR_1.5x1.5x1.5_90s 001 | 55.3 | 0.04
...                    | ...  | ...
SR_1.5x1.5x1.5_90s 002 | 64.8 | 0.00
SR_1.5x1.5x1.5_90s 002 | 69.6 | 0.04

我尝试使用 tidyr 函数 gather() 但结果并不令人满意。

这是我在这里提出的第一个问题,如果有任何信息遗漏,我深表歉意。

您想首先 gather 所有列,然后 spread 交替 ForceTime 行。

首先,我们将您的一小段数据重新创建为:

rtabla1 <- structure(list(SR_1.5x1.5x1.5_90s.001.Force = c(52.2, 55.3, 62.6, 66.5, 70.8, 75.9, 77.6, 78.7, 80.2, 83.8), SR_1.5x1.5x1.5_90s.001.Time = c(0, 0.004, 0.008, 0.012, 0.016, 0.02, 0.024, 0.028, 0.032, 0.036), 
SR_1.5x1.5x1.5_90s.002.Force = c(64.8, 69.6, 76, 80.2, 85.1, 
90.5, 94.1, 95.6, 99.7, 103.4), SR_1.5x1.5x1.5_90s.002.Time = c(0, 
0.004, 0.008, 0.012, 0.016, 0.02, 0.024, 0.028, 0.032, 0.036
)), .Names = c("SR_1.5x1.5x1.5_90s.001.Force", "SR_1.5x1.5x1.5_90s.001.Time", "SR_1.5x1.5x1.5_90s.002.Force", "SR_1.5x1.5x1.5_90s.002.Time"), row.names = c(NA, -10L), class = "data.frame")
##   SR_1.5x1.5x1.5_90s.001.Force SR_1.5x1.5x1.5_90s.001.Time SR_1.5x1.5x1.5_90s.002.Force SR_1.5x1.5x1.5_90s.002.Time
##1                          52.2                       0.000                         64.8                       0.000
##2                          55.3                       0.004                         69.6                       0.004
##3                          62.6                       0.008                         76.0                       0.008
##4                          66.5                       0.012                         80.2                       0.012
##5                          70.8                       0.016                         85.1                       0.016
##6                          75.9                       0.020                         90.5                       0.020
##7                          77.6                       0.024                         94.1                       0.024
##8                          78.7                       0.028                         95.6                       0.028
##9                          80.2                       0.032                         99.7                       0.032
##10                         83.8                       0.036                        103.4                       0.036

使用 tidyrdplyr:

library(dplyr)
library(tidyr)
result <- rtabla1 %>% mutate(Row=seq_len(n())) %>%                             ##1.
                      gather("ID","Vals",-Row) %>%                             ##2.
                      mutate(FT=ifelse(grepl(".Force$",ID), "Force", "Time"),  ##3.
                             ID=sub("(.Force$)|(.Time$)","",ID)) %>%
                      spread(FT,Vals) %>%                                      ##4.
                      select(-Row) %>%                                         ##5.
                      arrange(ID)                                              ##6.

备注:

  1. 首先添加一个仅包含行号的标识符列。
  2. gatherRow 之外的所有列,导致 ID 列包含收集的列名称。
  3. mutateID 列使用字符串操作形成列 FT。创建此 FT 列是为了识别收集到的行中哪些是 Force,哪些是 Time。后续spread中会用到。并创建其值以匹配结果的列名(即 "Force""Time")。在这里,使用 grepl 检查 ID 是否以 ".Force" 结尾。如果是,则将 FT 列设置为 "Force";否则,将 FT 列设置为 "Time"。然后,更新 ID 列以从其末尾删除 ".Force"".Time"
  4. 现在,spread 使用 FT 作为键和收集的值作为值。
  5. 从结果中删除 Row 列。
  6. 排序方式ID

使用一小段数据的result符合预期:

print(result)
##                       ID Force  Time
##1  SR_1.5x1.5x1.5_90s.001  52.2 0.000
##2  SR_1.5x1.5x1.5_90s.001  55.3 0.004
##3  SR_1.5x1.5x1.5_90s.001  62.6 0.008
##4  SR_1.5x1.5x1.5_90s.001  66.5 0.012
##5  SR_1.5x1.5x1.5_90s.001  70.8 0.016
##6  SR_1.5x1.5x1.5_90s.001  75.9 0.020
##7  SR_1.5x1.5x1.5_90s.001  77.6 0.024
##8  SR_1.5x1.5x1.5_90s.001  78.7 0.028
##9  SR_1.5x1.5x1.5_90s.001  80.2 0.032
##10 SR_1.5x1.5x1.5_90s.001  83.8 0.036
##11 SR_1.5x1.5x1.5_90s.002  64.8 0.000
##12 SR_1.5x1.5x1.5_90s.002  69.6 0.004
##13 SR_1.5x1.5x1.5_90s.002  76.0 0.008
##14 SR_1.5x1.5x1.5_90s.002  80.2 0.012
##15 SR_1.5x1.5x1.5_90s.002  85.1 0.016
##16 SR_1.5x1.5x1.5_90s.002  90.5 0.020
##17 SR_1.5x1.5x1.5_90s.002  94.1 0.024
##18 SR_1.5x1.5x1.5_90s.002  95.6 0.028
##19 SR_1.5x1.5x1.5_90s.002  99.7 0.032
##20 SR_1.5x1.5x1.5_90s.002 103.4 0.036