将列值从字符更改为数字或 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
我在 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