【问题标题】:Is there an R function that will allow me to gather conditionally?是否有一个 R 函数可以让我有条件地收集?
【发布时间】:2021-01-07 08:02:59
【问题描述】:

我有一个像这样的数据框(在变量 IV1-IV5 中​​,我存储了目标项目(F1、TI1、TI2、LI1、LI2)的问卷位置——它们又包含评级):

  SUBJECT EXP IV1 IV2 IV3 IV4 IV5 F1 TI1 TI2 LI1 LI2
1       1   n TI2 LI1  F1 LI2 TI1 25  75  75  50  50
2       2   n LI1 TI2 LI2  F1 TI1 30  70  70  45  45
3       3   e TI1  F1 TI2 LI2 LI1 25  70  70  50  50

我想把它变成一个长数据框,像这样:

     SUBJECT    EXP    TYPE    IV    Rating
   1       1      n     F1      3        25
   2       1      n     TI1     5        75
   3       1      n     TI2     1        50
   4       1      n     LI1     2        50
   5       1      n     LI2     4        50
   6       2      n     F1      4        30
   7       2      n     TI1     5        70
   8       2      n     TI2     2        70
   9       2      n     LI1     1        45
  10       2      n     LI2     3        45
  11       3      e     F1      2        25
  12       3      e     TI1     1        70
  13       3      e     TI2     3        70
  14       3      e     LI1     5        50
  15       3      e     LI2     4        50

我知道 collect() 但我不认为它可以自己进行这种转换。有什么比自己写一堆 ifelse 语句更快的方法吗?

我的一个想法是创建一个新列并有条件地 unite() 两个单元格(对于每个 TI col 将评级与具有匹配值的 IV-col 名称结合起来),然后在这些组合列中收集()之后分开)。但它似乎太乏味了——我相信——一定是一个普遍的问题。任何指针都会有所帮助——谢谢!

编辑:我的 MWE 并没有像应有的那样代表我的问题。我在上面的两个示例 DF 中更改了一些内容。

【问题讨论】:

  • 好的,谢谢。我搞砸了一点。
  • 在输出中,F1 是 IV3 下的第一个值(这是“3”的来源),评级“25”是 F1 中的第一个值。在输入 df 中,变量 F1、TI1、TI2、LI1 和 LI2 包含问卷项目的评分。 IV1-5(用于“内部变量”)包含问卷项目的位置。输出应该是一个长 df,每行有一个评级/观察,其在问卷中的位置位于单独的列中。
  • 我想,F1, IV3, 25 而不是 F1, 3, 25 将是显示所需输出的更清晰的方式,第二行是 TI1, IV5, 75。

标签: r tidyr data-cleaning data-conversion


【解决方案1】:

这是我能想到的。我对gather() 的理解要好得多,pivot_longer() 不断抛出错误。

df1 <- df %>%
  gather("TYPE", "RATING", -SUBJECT, -EXP, -IV1, -IV2, -IV3, -IV4, -IV5) %>%
  gather("POS", "foobar", -SUBJECT, -EXP, -TYPE, -RATING) %>%
  filter(TYPE == foobar) %>%
  select(-foobar)

这是我可以接受的初步结果(并根据需要进行一些清理):

SUBJECT EXP TYPE RATING POS
      1   n  TI2     75 IV1
      1   n  LI1     50 IV2
      1   n   F1     25 IV3
      1   n  LI2     50 IV4
      1   n  TI1     75 IV5
      2   n  LI1     45 IV1
      2   n  TI2     70 IV2
      2   n  LI2     45 IV3
      2   n   F1     30 IV4
      2   n  TI1     70 IV5
      3   e  TI1     70 IV1
      3   e   F1     25 IV2
      3   e  TI2     70 IV3
      3   e  LI2     50 IV4
      3   e  LI1     50 IV5

我很乐意接受改进建议。到目前为止,感谢 Ronak Shah 的指导。

【讨论】:

  • 使用 pivot_longer 你可以这样做:df %&gt;% pivot_longer(cols = F1:LI2, names_to = 'TYPE', values_to = 'RATING') %&gt;% pivot_longer(cols = starts_with('IV'), names_to = 'POS', values_to = 'foobar') %&gt;% filter(TYPE == foobar) %&gt;% select(-foobar)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-04
  • 1970-01-01
  • 1970-01-01
  • 2021-08-08
  • 2020-02-21
  • 2021-12-15
  • 1970-01-01
相关资源
最近更新 更多