基于特定分隔符格式的列拆分
Column Split based on certain separator format
我有一个格式来分隔我将拥有这些数据的位置:
df = data.frame(id=c(1,2),name=c('A~B~C','A~B~D'),value=c('1~2~3','1~~2'))
id name value
1 A~B~C 1~2~3
2 A~B~D 1~~2
预计会有以下输出,其中列名是原始列名后跟名称列中的文本:
id value_A value_B value_C value_D
1 1 2 3
2 1 2
我设法通过使用许多嵌套的 for 循环逐行处理我的数据来实现拆分。它适用于小样本数据,但一旦数据变大,时间就成了问题。
此外,可以有 1 个以上的值列,但它们都应映射到相同的名称列中。
示例输出:
id value_A value_B value_C value1_A value1_B value1_C
1 1 2 3 1 2 3
2 1 2 3 1 2 3
你可以试试dplyr
:
library(tidyverse)
df %>%
separate_rows(name, value, sep = "~") %>%
spread(name, value)
id A B C D
1 1 1 2 3 <NA>
2 2 1 <NA> 2
您可以用 fill = ""
中指定的任何内容填充空单元格,而不是 NA
或者baseR和reshape2
:
a <- strsplit(as.character(df$name), "~")
b <- strsplit(as.character(df$value), "~")
df2 <- do.call(rbind.data.frame, Map(cbind, df$id, a, b))
library(reshape2)
dcast(df2, V1~V2, value.var = "V3")
A B C D
1 1 2 3 <NA>
2 1 <NA> 2
这是一个使用 cSplit/dcast
的选项。使用 cSplit
将行拆分为 'long' 格式,将 dcast
拆分为 'wide' 格式
library(splitstackshape)
dcast(cSplit(df, c('name','value'), '~', 'long')[!is.na(value)], id ~ paste0('value_', name))
# id value_A value_B value_C value_D
#1: 1 1 2 3 NA
#2: 2 1 NA NA 2
我有一个格式来分隔我将拥有这些数据的位置:
df = data.frame(id=c(1,2),name=c('A~B~C','A~B~D'),value=c('1~2~3','1~~2'))
id name value
1 A~B~C 1~2~3
2 A~B~D 1~~2
预计会有以下输出,其中列名是原始列名后跟名称列中的文本:
id value_A value_B value_C value_D
1 1 2 3
2 1 2
我设法通过使用许多嵌套的 for 循环逐行处理我的数据来实现拆分。它适用于小样本数据,但一旦数据变大,时间就成了问题。
此外,可以有 1 个以上的值列,但它们都应映射到相同的名称列中。 示例输出:
id value_A value_B value_C value1_A value1_B value1_C
1 1 2 3 1 2 3
2 1 2 3 1 2 3
你可以试试dplyr
:
library(tidyverse)
df %>%
separate_rows(name, value, sep = "~") %>%
spread(name, value)
id A B C D
1 1 1 2 3 <NA>
2 2 1 <NA> 2
您可以用 fill = ""
NA
或者baseR和reshape2
:
a <- strsplit(as.character(df$name), "~")
b <- strsplit(as.character(df$value), "~")
df2 <- do.call(rbind.data.frame, Map(cbind, df$id, a, b))
library(reshape2)
dcast(df2, V1~V2, value.var = "V3")
A B C D
1 1 2 3 <NA>
2 1 <NA> 2
这是一个使用 cSplit/dcast
的选项。使用 cSplit
将行拆分为 'long' 格式,将 dcast
拆分为 'wide' 格式
library(splitstackshape)
dcast(cSplit(df, c('name','value'), '~', 'long')[!is.na(value)], id ~ paste0('value_', name))
# id value_A value_B value_C value_D
#1: 1 1 2 3 NA
#2: 2 1 NA NA 2