整理 R 数据框中的数字数组

Tidying arrays of numbers in R data frame

如何整理下面的数据框

data.frame(a  = c(1,2), values = c("[1.1, 1.2, 1.3]", "[2.1, 2.2]"))

 a          values
1 [1.1, 1.2, 1.3]
2      [2.1, 2.2]

结果应该是

data.frame(a  = c(1,1,1,2,2), values = c(1.1, 1.2, 1.3, 2.1, 2.2))
  a values
 1    1.1
 1    1.2
 1    1.3
 2    2.1
 2    2.2

我们可以在listunnest

中提取str_extract_all的数字
library(dplyr)
library(stringr)
library(tidyr)
df1 %>%
    mutate(values = str_extract_all(values, "[0-9.]+")) %>% 
    unnest(values) %>% 
    type.convert(as.is = TRUE)

-输出

# A tibble: 5 × 2
      a values
  <int>  <dbl>
1     1    1.1
2     1    1.2
3     1    1.3
4     2    2.1
5     2    2.2

或者另一种选择是使用 reticulate:py_eval 评估 python 对象,然后 unnest list

library(reticulate)
df1 %>%
    rowwise %>%
     mutate(values = list(py_eval(values))) %>%
     unnest(values)

-输出

# A tibble: 5 × 2
      a values
  <dbl>  <dbl>
1     1    1.1
2     1    1.2
3     1    1.3
4     2    2.1
5     2    2.2

数据

df1 <- data.frame(a  = c(1,2), values = c("[1.1, 1.2, 1.3]", "[2.1, 2.2]"))

另一个可能的解决方案:

library(tidyverse)

df <- data.frame(a  = c(1,2), values = c("[1.1, 1.2, 1.3]", "[2.1, 2.2]"))

df %>% 
  separate(values, into=LETTERS[1:5], sep="\[|,|\]", fill="right",convert=T) %>% 
  pivot_longer(-a, values_drop_na = T) %>% 
  select(-name)

#> # A tibble: 5 × 2
#>       a value
#>   <dbl> <dbl>
#> 1     1   1.1
#> 2     1   1.2
#> 3     1   1.3
#> 4     2   2.1
#> 5     2   2.2

另一个基本 R 选项使用 eval + expression + gsub

with(
  df,
  type.convert(
    setNames(
      rev(
        stack(
          sapply(
            setNames(values, a),
            function(x) eval(str2expression(gsub("\[(.*)\]", "c(\1)", x)))
          )
        )
      ), names(df)
    ),
    as.is = TRUE
  )
)

给予

  a values
1 1    1.1
2 1    1.2
3 1    1.3
4 2    2.1
5 2    2.2

刚刚意识到与@akrun 的回答类似,可以使用 jsonlite::fromJSON 将字符串转换为向量。这不会对数字格式做出任何特定假设,也不需要使用 Python.

df <- data.frame(a  = c(1,2), values = c("[1.1, 1.2, 1.3]", "[2.1, 2.2]"))
df %>%  
    mutate(values = map(values, jsonlite::fromJSON)) %>% 
    unnest(values)