如何使用R

时间:2019-02-15 10:15:53

标签: r tidyr

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

样品列数据

[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

因此,输出应与数据集中提供的输出相同。所获得的值会发生巨大变化。

我确实知道我的代码存在问题,但是我无法弄清楚该如何纠正。

任何输入都会很有帮助。

根据评论进行

编辑

1 个答案:

答案 0 :(得分:0)

假设您有一个不需要的列表列,想要转换为多个列。您没有提供可重复的数据,因此我将使用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列的单行数据框,因此我们需要{{ 1}}函数可转置每个列表。

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

(此步骤可能会得到改进,但这应该可行。)

将新数据添加回原始数据

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

t

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>