我有一个像这样的庞大数据集:
customer_id customer_math
15251 10001010
10101 11111111
84787 10101010
我想在每个字符处拆分customer_math以获得这样的df:
customer_id 2012 2013 2014 2015 2016 2017 2018 2019
15251 1 0 0 0 1 0 1 0
10101 1 1 1 1 1 1 1 1
84787 1 0 1 0 1 0 1 0
我尝试过但失败了。
您能帮我吗?
非常感谢您的支持!
答案 0 :(得分:4)
这是一种可能的解决方案,它对正向(?=.)
进行正则表达式拆分,以在每个字符之前生成拆分。
out <- strsplit(as.character(df$customer_math), "(?=.)", perl=TRUE)
data.frame(df, do.call(rbind, out))
customer_id customer_math X1 X2 X3 X4 X5 X6 X7 X8
1 15251 10001010 1 0 0 0 1 0 1 0
2 10101 11111111 1 1 1 1 1 1 1 1
3 84787 10101010 1 0 1 0 1 0 1 0
数据:
df <- data.frame(customer_id=c(15251, 10101, 84787),
customer_math=c(10001010, 11111111, 10101010))
编辑:
正如@Sotos所指出的,将strsplit
与""
空字符串一起使用作为分隔符也是可以的。
答案 1 :(得分:2)
一种修复列标签的Stock Code
Quantity on Hand
Quantity on Order
SELECT dbo_ICITEM.FMTITEMNO, SumOfQUANTITY, SumOfQTYORDERED
FROM (
SELECT dbo_ICITEM.FMTITEMNO, Sum(dbo_ICIVAL.QUANTITY) AS SumOfQUANTITY
FROM dbo_ICIVAL LEFT JOIN dbo_ICITEM ON dbo_ICIVAL.ITEMNO = dbo_ICITEM.ITEMNO
WHERE (dbo_ICIVAL.LOCATION='1002')
GROUP BY dbo_ICITEM.FMTITEMNO
HAVING Sum(dbo_ICIVAL.QUANTITY)<>0
UNION ALL
(SELECT dbo_OEORDD.ITEM, Sum(dbo_OEORDD.QTYORDERED) AS SumOfQTYORDERED
FROM dbo_OEORDD
WHERE (((dbo_OEORDD.LOCATION) In ('1002')) AND ((dbo_OEORDD.COMPLETE)=0))
GROUP BY dbo_OEORDD.ITEM
HAVING Sum(dbo_OEORDD.QTYORDERED) <> 0)
)
;
解决方案可以是:
代码
tidyverse
结果
df %>%
mutate(customer_math = str_replace_all(customer_math,
"\\B", " ")) %>%
separate(customer_math,
into = as.character(2012:2019),
sep = " ")
答案 2 :(得分:1)
我们可以使用cSplit
中的splitstackshape
并将每个字符分成不同的列。
splitstackshape::cSplit(df, "customer_math", sep = "", stripWhite = FALSE)
# customer_id customer_math_1 customer_math_2 customer_math_3 customer_math_4
#1: 15251 1 0 0 0
#2: 10101 1 1 1 1
#3: 84787 1 0 1 0
# customer_math_5 customer_math_6 customer_math_7 customer_math_8
#1: 1 0 1 0
#2: 1 1 1 1
#3: 1 0 1 0
答案 3 :(得分:1)
对于这样的任务,我想保持打开状态以扩展到未知数量的列。从2012年开始,列名称已有数年的历史,如果您采取一些额外的步骤来重塑数据,那么这些年可能就不需要太多的硬编码了。
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
将拆分一列并为其中的每个项目创建一行。您可以使用诸如tidyr::separate_rows
之类的正则表达式来匹配每个字符之间的非空格。通过从2012年开始沿每个ID的行数进行计数来创建年份列。 (可选)将这些“ 0” /“ 1”值转换为数字,然后重新调整为宽数据。
"\\B"