【问题标题】:How to separate a List into Multiple Columns using R如何使用 R 将列表分成多列
【发布时间】:2019-07-09 11:09:22
【问题描述】:

数据集中的一列,当前由一个列表组成。我想把它转换成多列。

示例列数据

[2060657.4999428242, 2143589.028916441, 2196493.4902963564, 2316188.419917967, 2130287.151382759, 1852280.080035247]

我目前在 R 中使用 'tidyr' 包将此列表拆分为多个列;

Output <- Output %>% separate(amount, c("TA0", "TA1", "TA2", "TA3", "TA4", "TA5", "TA6"),
                           extra = 'drop', fill = 'left')

我正在获取多个列,但是结果不同,例如;

| TA0 | TA1    | TA2       | TA3    | TA4      | TA5      | TA6     |
---------------------------------------------------------------------
  NA   1839801  6996446848   1901519  605394691   1798929  9497592524

然而,输出应该与数据集中提供的相同。获得的值发生了巨大的变化。

我明白,我的代码有问题,但是,我不知道如何纠正它。

任何输入都会很有帮助。

编辑基于评论。

【问题讨论】:

  • 想要的输出是什么样子的?

标签: r tidyr


【解决方案1】:

假设您有一个不需要的列表列,您想将其转换为多个列。您没有提供可重现的数据,所以我将使用 iris 数据集创建这种情况。

使用数字列表列创建数据集

example_data <-
    iris %>%
    mutate(list_col = list(rnorm(7))) 

此示例假设您在相关列中的数据实际上是一个列表。不需要的列表列称为list_col。所以示例数据如下所示:

Source: local data frame [150 x 6]
Groups: <by row>

# A tibble: 150 x 6
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species list_col 
          <dbl>       <dbl>        <dbl>       <dbl> <fct>   <list>   
 1          5.1         3.5          1.4         0.2 setosa  <dbl [7]>
 2          4.9         3            1.4         0.2 setosa  <dbl [7]>
 3          4.7         3.2          1.3         0.2 setosa  <dbl [7]>
 4          4.6         3.1          1.5         0.2 setosa  <dbl [7]>
 5          5           3.6          1.4         0.2 setosa  <dbl [7]>
 6          5.4         3.9          1.7         0.4 setosa  <dbl [7]>
 7          4.6         3.4          1.4         0.3 setosa  <dbl [7]>
 8          5           3.4          1.5         0.2 setosa  <dbl [7]>
 9          4.4         2.9          1.4         0.2 setosa  <dbl [7]>
10          4.9         3.1          1.5         0.1 setosa  <dbl [7]>
# ... with 140 more rows

创建列名

接下来,告诉 R 你要添加的新列名。

my_new_column_names <- c("TA0", "TA1", "TA2", "TA3", "TA4", "TA5", "TA6")

请注意我添加到iris 以创建example_data 的随机列表的长度等于我们假设的新列(名称)的数量。此外,数据帧每一行的列表长度是相同的。

隔离列表数据(即列表列)并操作到新的数据帧中

new_df <- example_data %>%
    pull(list_col) %>%
    map(. , ~{setNames(.x, my_new_column_names)}) %>%
    map(., ~{.x %>% t %>% as.tibble}) %>%
    bind_rows() 

这里,pull() 只是隔离了列表列,然后第一个 map() 将每个列表元素的名称设置为 my_new_column_names 中指定的名称。第二个map() 将列表转换为数据帧。对于每个列表(即原始example_data 的每一行),我们不想要具有 7 个值和命名行的单列数据帧,我们想要具有 7 列的单行数据帧,因此我们需要 t 函数转置每个列表。

最后的 bind_rows() 只是将 1×7 数据帧列表转换为单个多行数据帧。

(这一步可能会有所改进,但这应该可以。)

将新数据添加回原始数据

最后一步是将现在正确格式化的数据添加回原始数据,并删除现在多余的列表列。

corrected_data <- example_data %>%
    bind_cols(new_df) %>%
    select(-list_col)

corrected_data 现在应该是这样的

Source: local data frame [150 x 12]
Groups: <by row>

# A tibble: 150 x 12
   Sepal.Length Sepal.Width Petal.Length Petal.Width Species     TA0    TA1
          <dbl>       <dbl>        <dbl>       <dbl> <fct>     <dbl>  <dbl>
 1          5.1         3.5          1.4         0.2 setosa  -0.170   0.225
 2          4.9         3            1.4         0.2 setosa   1.32   -2.00 
 3          4.7         3.2          1.3         0.2 setosa  -0.517   1.60 
 4          4.6         3.1          1.5         0.2 setosa   0.0867 -0.473
 5          5           3.6          1.4         0.2 setosa   0.138   0.213
 6          5.4         3.9          1.7         0.4 setosa  -0.213   0.892
 7          4.6         3.4          1.4         0.3 setosa  -0.804  -1.34 
 8          5           3.4          1.5         0.2 setosa   0.754  -2.57 
 9          4.4         2.9          1.4         0.2 setosa  -0.138   1.11 
10          4.9         3.1          1.5         0.1 setosa  -0.814   1.24 
# ... with 140 more rows, and 5 more variables: TA2 <dbl>, TA3 <dbl>,
#   TA4 <dbl>, TA5 <dbl>, TA6 <dbl>

...我认为这是你想要的。

如果你想把它全部粉碎成一串管道函数,它看起来像

example_data %>%
        pull(list_col) %>%
        map(. , ~{setNames(.x, my_new_column_names)}) %>%
        map(., ~{.x %>% t %>% as.tibble}) %>%
        bind_rows() %>%
        bind_cols(example_data, .) %>%
        select(-list_col)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-19
    • 1970-01-01
    • 2017-03-18
    • 1970-01-01
    • 2021-12-14
    • 2020-10-06
    • 1970-01-01
    相关资源
    最近更新 更多