您好我有一个以逗号分隔的列的表,我需要将逗号分隔的值转换为新行。例如,给定的表是
Name Start End
A 1,2,3 4,5,6
B 1,2 4,5
C 1,2,3,4 6,7,8,9
我需要将其转换为
Name Start End
A 1 4
A 2 5
A 3 6
B 1 4
B 2 5
C 1 6
C 2 7
C 3 8
C 4 9
我可以使用VB脚本来做到这一点,但我需要使用R来解决它 任何人都可以解决这个问题吗?
答案 0 :(得分:3)
您可能已在SO上提出此问题,因为没有处理统计信息的问题:)
无论如何,我编写了一个非常复杂和丑陋的解决方案,可能对你有用:
# load your data
x <- structure(list(Name = c("A", "B", "C"), Start = c("1,2,3", "1,2",
"1,2,3,4"), End = c("4,5,6", "4,5", "6,7,8,9")), .Names = c("Name",
"Start", "End"), row.names = c(NA, -3L), class = "data.frame")
在R中看起来像:
> x
Name Start End length
1 A 1,2,3 4,5,6 3
2 B 1,2 4,5 2
3 C 1,2,3,4 6,7,8,9 4
借助strsplit
来电进行数据转换:
data <- data.frame(cbind(
rep(x$Name,as.numeric(lapply(strsplit(x$Start,","), length))),
unlist(lapply(strsplit(x$Start,","), cbind)),
unlist(lapply(strsplit(x$End,","), cbind))
))
命名新数据框:
names(data) <- c("Name", "Start", "End")
看起来像:
> data
Name Start End
1 A 1 4
2 A 2 5
3 A 3 6
4 B 1 4
5 B 2 5
6 C 1 6
7 C 2 7
8 C 3 8
9 C 4 9
答案 1 :(得分:2)
这是一种适合您的方法。我假设你的三个输入向量在不同的对象中。我们将创建这些输入的列表并编写一个处理每个对象的函数,并以data.frame
的形式返回它们与plyr。
这里需要注意的是将字符向量拆分为它的组成部分,然后使用as.numeric
转换字符形式的数字。由于R按列填充矩阵,我们定义一个2列矩阵,让R为我们填充值。然后,我们检索“名称”列并将其全部放在data.frame
中。 plyr
非常适合处理列表并自动将其转换为data.frame
。
library(plyr)
a <- paste("A",1, 2,3,4,5,6, sep = ",", collapse = "")
b <- paste("B",1, 2,4,5, sep = ",", collapse = "")
c <- paste("C",1, 2,3,4,6,7,8,9, sep = ",", collapse = "")
input <- list(a,b,c)
splitter <- function(x) {
x <- unlist(strsplit(x, ","))
out <- data.frame(x[1], matrix(as.numeric(x[-1]), ncol = 2))
colnames(out) <- c("Name", "Start", "End")
return(out)
}
ldply(input, splitter)
输出:
> ldply(input, splitter)
Name Start End
1 A 1 4
2 A 2 5
3 A 3 6
4 B 1 4
5 B 2 5
6 C 1 6
7 C 2 7
8 C 3 8
9 C 4 9
答案 2 :(得分:1)
separate_rows()
中的tidyr
函数是具有多个分隔值的观察的老大......
# create data
library(tidyverse)
d <- data_frame(
Name = c("A", "B", "C"),
Start = c("1,2,3", "1,2", "1,2,3,4"),
End = c("4,5,6", "4,5", "6,7,8,9")
)
d
# # A tibble: 3 x 3
# Name Start End
# <chr> <chr> <chr>
# 1 A 1,2,3 4,5,6
# 2 B 1,2 4,5
# 3 C 1,2,3,4 6,7,8,9
# tidy data
separate_rows(d, Start, End)
# # A tibble: 9 x 3
# Name Start End
# <chr> <chr> <chr>
# 1 A 1 4
# 2 A 2 5
# 3 A 3 6
# 4 B 1 4
# 5 B 2 5
# 6 C 1 6
# 7 C 2 7
# 8 C 3 8
# 9 C 4 9
# use convert set to TRUE for integer column modes
separate_rows(d, Start, End, convert = TRUE)
# # A tibble: 9 x 3
# Name Start End
# <chr> <int> <int>
# 1 A 1 4
# 2 A 2 5
# 3 A 3 6
# 4 B 1 4
# 5 B 2 5
# 6 C 1 6
# 7 C 2 7
# 8 C 3 8
# 9 C 4 9
答案 3 :(得分:0)
这是另一个,只是为了好玩。将d
作为原始数据。
f <- function(x, ul = TRUE)
{
x <- deparse(substitute(x))
if(ul) unlist(strsplit(d[[x]], ','))
else strsplit(d[[x]], ',')
}
> data.frame(Name = rep(d$Name, sapply(f(End, F), length)),
Start = f(Start), End = f(End))
# Name Start End
# 1 A 1 4
# 2 A 2 5
# 3 A 3 6
# 4 B 1 4
# 5 B 2 5
# 6 C 1 6
# 7 C 2 7
# 8 C 3 8
# 9 C 4 9