将列值从字符更改为数字或 R 中的重复行

Change column value from character to number or duplicate row in R

我在 R 中的某些数据中遇到变量问题。我有一个 table 看起来像这样,

Variable X Variable Y
11 [1]
15 [400]
17 [1,2]
21 [13,14]

我想做的是,对于 'Variable Y' 中的每个条目,如果方括号中只有一个数字,我想去掉方括号。如果有多个数字,我想去掉括号然后复制整行,只需在每个副本中更改 'Variable Y' 中的值。我基本上希望 table 看起来像这样,

Variable X Variable Y
11 1
15 400
17 1
17 2
21 13
21 14

我已经能够使用 readr 包中的解析数字函数将单个括号条目转换为数字,但它非常慢,所以我想改进它。我也不知道如何根据方括号中的多个条目获取重复项。任何帮助将不胜感激,谢谢。

如果您使用 tidyverse functions, you can parse the strings as JSON arrays using fromJSON and then use unnest 将数组项展开为多行:

library(tidyverse)
library(jsonlite)

d %>%
    mutate(Y_lst = map(Y, fromJSON)) %>%
    unnest(Y_lst)

在你的例子中:

> d
# A tibble: 4 x 2
      X Y      
  <dbl> <chr>  
1    11 [1]    
2    15 [400]  
3    17 [1,2]  
4    21 [13,14]

> d %>% mutate(Y_lst = map(Y, fromJSON)) %>% unnest(Y_lst)
# A tibble: 6 x 3
      X Y       Y_lst
  <dbl> <chr>   <int>
1    11 [1]         1
2    15 [400]     400
3    17 [1,2]       1
4    17 [1,2]       2
5    21 [13,14]    13
6    21 [13,14]    14

gsub 括号和 strsplit 在逗号处,unlist 嵌套列然后用 type.convert 获取数字。

dat |>
  transform(Y=type.convert(strsplit(gsub('\[|\]', '', Y), ','), as.is=TRUE)) |>
  split(x=_, dat$X) |>
  lapply(\(x) data.frame(X=x$X, Y=unlist(x$Y))) |>
  c(make.row.names=FALSE) |>
  do.call(what='rbind')
#    X   Y
# 1 11   1
# 2 15 400
# 3 17   1
# 4 17   2
# 5 21  13
# 6 21  14

注: 使用 R 4.2。

或者更经典:

r <- transform(dat, Y=type.convert(strsplit(gsub('\[|\]', '', Y), ','), as.is=TRUE))
r <- by(r, r$X, function(x) data.frame(X=x$X, Y=unlist(x$Y)))
do.call(rbind, c(r, make.row.names=FALSE))
#    X   Y
# 1 11   1
# 2 15 400
# 3 17   1
# 4 17   2
# 5 21  13
# 6 21  14

数据:

dat <- structure(list(X = c(11L, 15L, 17L, 21L), Y = c("[1]", "[400]", 
"[1,2]", "[13,14]")), class = "data.frame", row.names = c(NA, 
-4L))

可以先去掉方括号,然后separate_rows:

library(dplyr)
library(tidyr)
df %>%
  mutate(Y = gsub("\[|\]", "", Y)) %>%
  separate_rows(Y, sep = ",")
# A tibble: 6 × 2
      X Y    
  <dbl> <chr>
1    11 1    
2    15 400  
3    17 1    
4    17 2    
5    21 13   
6    21 14