我有以下数据框(df),对于每个参与者,列"等级"是通过粘贴一些项目的分数来建立的。例如,参与者' 1'已经获得4个项目' a' 7项目' b'和8项目' c'。 (注意成绩是一个角色)。另请注意参与者' 2'只有两个分数(假设这是一个与参与者不同的分数' 1)。
df = data.frame(participants = c(1, 1, 2),
variables = c('abc', 'ef', 'abc'),
grades= c('478', '58', '942'),
stringsAsFactors = FALSE)
participants variables grades
1 1 abc 478
2 1 ef 58
3 2 abc 942
(我的数据包含100,000行,如上所述。)
我希望将数据转换为整洁的样式,如下所示:
participants variables grades
1 1 a 4
2 1 b 7
3 1 c 8
4 1 e 5
5 1 f 8
6 2 a 9
7 2 b 4
8 2 c 2
我在这里做了什么
variables = lapply(X=1:length(df$variables), FUN=function(X) {
strsplit(df$variables[X], "") %>% .[[1]]}) %>% reduce(c)
grades = lapply(X=1:length(df$grades), FUN=function(X) {
strsplit(df$grades[X], "") %>% .[[1]]}) %>% reduce(c)
participants = lapply(X=1:length(df$participants), FUN=function(X) {
rep(df$participants[X], nchar(df$variables[X])) })%>% reduce(c)
data.frame(participants, variables, grades)
然而,使用我的真实数据在我的机器上花费几分钟,我觉得它实际上效率不高,因为我需要3个不同的调用。
任何有效获取整洁数据的想法都会受到欢迎(我与tidyr / dplyr合作)
答案 0 :(得分:3)
您可以使用strsplit
和unnest
:
library(tidyverse)
df %>% mutate_at(vars(variables,grades),~strsplit(.,"")) %>% unnest
# participants variables grades
# 1 1 a 4
# 2 1 b 7
# 3 1 c 8
# 4 1 e 5
# 5 1 f 8
# 6 2 a 9
# 7 2 b 4
# 8 2 c 2
答案 1 :(得分:2)
data.table解决方案
setDT(df)
df[,lapply(.SD,function(x){strsplit(x,"") %>% unlist}),.SDcols=c("variables","grades"),by=participants]
结果:
participants variables grades
1: 1 a 4
2: 1 b 7
3: 1 c 8
4: 1 e 5
5: 1 f 8
6: 2 a 9
7: 2 b 4
8: 2 c 2
>