【问题标题】:Transpose a dataframe in case of rows contain two values for the same variable in R如果行包含 R 中同一变量的两个值,则转置数据帧
【发布时间】:2020-02-20 14:07:57
【问题描述】:

我正在处理一个数据框,其中包含一个名为“Marker”的变量,该变量显示了我收集的所有样本的两个值。 例如,数据框如下:

Sample.File Sample.Name Marker value
1            a         a_1    xxx    16
2            a         a_1    xxx    18
3            a         a_1    yyy    16
4            a         a_1    yyy    20
5            a         a_1    zzz     9
6            a         a_1    zzz    13
7            b         b_1    xxx    10
8            b         b_1    xxx    10
9            b         b_1    yyy     6
10           b         b_1    yyy    12
11           b         b_1    zzz    14
12           b         b_1    zzz    14

由以下代码提供:

data <- data.frame(
   Sample.File = as.factor(c("a", "a", "a", "a", "a", "a", "b", "b", "b", "b",
                             "b", "b")),
   Sample.Name = as.factor(c("a_1", "a_1", "a_1", "a_1", "a_1", "a_1", "b_1",
                             "b_1", "b_1", "b_1", "b_1", "b_1")),
        Marker = as.factor(c("xxx", "xxx", "yyy", "yyy", "zzz", "zzz", "xxx",
                             "xxx", "yyy", "yyy", "zzz", "zzz")),
   value = c(16L, 18L, 16L, 20L, 9L, 13L, 10L, 10L, 6L, 12L, 14L, 14L)
)

我想使用的新数据框应该通过转置当前数据来实现,但要为所有收集的样本维护列 Sample.File 和 Sample.Name。此外,我想为标记为“值”的列获取新变量以如下标记(例如 xxx & xxx.1、yyy & yyy.1、zzz & zzz.1)。

我想要实现的表如下所示:

  Sample.File Sample.Name xxx xxx.1 yyy yyy.1 zzz zzz.1
1           a         a_1  16    18  16    20   9    13
2           b         b_1  10    10   6    12  14    14

我想使用代码而不将报告的标签名称写入“标记”列(因为我可以获得多达 100 个不同的标签)。 我尝试使用以下代码,但无法实现我的目标:

我尝试使用以下代码,但无法实现目标:

library(dplyr)
library(tidyr)
data %>%
  gather(Sample.File, Sample.Name) %>%
  spread(value)

Error: `var` must evaluate to a single number or a column name, not a double vector
Run `rlang::last_error()` to see where the error occurred.
In addition: Warning message:
attributes are not identical across measure variables;
they will be dropped

如果有人能解决这个问题,我将非常感激!

【问题讨论】:

    标签: r dplyr tidyr


    【解决方案1】:

    这是一种方法。我们可以为每个Marker 创建一个ID,然后创建一个列。之后,我们可以将其转换为宽格式。

    library(dplyr)
    library(tidyr)
    
    data2 <- data %>%
      group_by_at(vars(-value)) %>%
      mutate(N = row_number() - 1) %>%
      unite(col = "Marker", Marker, N, sep = ".") %>%
      pivot_wider(names_from = "Marker", values_from = "value") %>%
      ungroup()
    data2
    # # A tibble: 2 x 8
    #   Sample.File Sample.Name xxx.0 xxx.1 yyy.0 yyy.1 zzz.0 zzz.1
    #   <fct>       <fct>       <int> <int> <int> <int> <int> <int>
    # 1 a           a_1            16    18    16    20     9    13
    # 2 b           b_1            10    10     6    12    14    14
    

    【讨论】:

    • 亲爱的@www,感谢您的帮助,但您的方法似乎为我提供了以下错误:Error: row_number() should only be called in a data context Run rlang::last_error() to see where the error occurred.您能帮我解决这个问题吗??
    • 您在使用您的示例数据框运行我的解决方案时有任何问题吗?
    • 很奇怪。把row_number()改成1:n()怎么样?
    • 我替换了它,但我不断收到以下错误:Error: n() should only be called in a data context Run rlang::last_error() to see where the error occurred.
    猜你喜欢
    • 2015-12-01
    • 1970-01-01
    • 2021-11-05
    • 2022-01-20
    • 2022-11-02
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 2019-07-18
    相关资源
    最近更新 更多