在R中将1-many列解析为新data.frame的优雅方法
我从excel电子表格中读取了一些数据,其中策展人不知道关系数据库和处理1-多个关系,因此将多个变量放在一列中:在R中将1-many列解析为新data.frame的优雅方法,r,reshape,R,Reshape,我从excel电子表格中读取了一些数据,其中策展人不知道关系数据库和处理1-多个关系,因此将多个变量放在一列中: >df <- data.frame(id=c("X1", "X23", "X5"), vars=c("foo, bar, hello", "world", NA), var2=c(1,2,3)) >df id vars var2 1 X1 foo, bar, hello 1 2 X23 world 2 3
>df <- data.frame(id=c("X1", "X23", "X5"), vars=c("foo, bar, hello", "world", NA), var2=c(1,2,3))
>df
id vars var2
1 X1 foo, bar, hello 1
2 X23 world 2
3 X5 <NA> 3
我能够将vars
列解析为一个列表,其中每个条目都是变量向量:
>library(stringr)
>halfway <- str_split(df$vars, pattern=", ")
>halfway
[[1]]
[1] "foo" "bar" "hello"
[[2]]
[1] "world"
[[3]]
[1] NA
>库(stringr)
>半路
[[1]]
[1] “foo”“bar”“你好”
[[2]]
[1] “世界”
[[3]]
[1] NA
但我不确定如何将此列表转换为长的data.frame
我已经尝试过了,但是如果不丢失每个变量所属ID的信息(使用unlist
),我无法将其转换为长格式。
我还研究了重塑
,但它似乎没有达到我想要的效果
我可以使用for循环以迭代方式构建新表,但效率非常低。是否有一个优雅的解决方案?这可以通过使用
数据以非常简单的方式完成。表包:
library(data.table)
dt = as.data.table(df)
df2 = dt[, list(var=str_split(vars, ", ")[[1]]), by=id]
df2 = df2[!is.na(var), ]
这样做的一个优点是,如果您有多个ID列(例如,ID、id2、id3),您可以将其更改为
df2 = dt[, list(var=strsplit(vars, ", ")[[1]]), by=c("id", "id2", "id3")]
这可以通过使用数据以非常简单的方式完成。表包:
library(data.table)
dt = as.data.table(df)
df2 = dt[, list(var=str_split(vars, ", ")[[1]]), by=id]
df2 = df2[!is.na(var), ]
这样做的一个优点是,如果您有多个ID列(例如,ID、id2、id3),您可以将其更改为
df2 = dt[, list(var=strsplit(vars, ", ")[[1]]), by=c("id", "id2", "id3")]
expand.grid
函数通常用于重塑数据。例如:
> expand.grid(df[1,1],halfway[[1]])
Var1 Var2
1 X1 foo
2 X1 bar
3 X1 hello
您可以使用apply
对数据框的每一行执行此操作:
threequarterway <- lapply(seq(nrow(df)),function(i) expand.grid(df[i,1],halfway[[i]]))
df2 <- do.call(rbind,threequarterway)
最后,如David Robinson的回答中所述,消除NA争议:
df2 = df2[!is.na(df2[,2]),]
(David的回答是在我键入时出现的,这可能是一种更好的方法,但我想您可能想知道expand.grid
。expand.grid
函数通常对重塑数据有用。例如:
> expand.grid(df[1,1],halfway[[1]])
Var1 Var2
1 X1 foo
2 X1 bar
3 X1 hello
您可以使用apply
对数据框的每一行执行此操作:
threequarterway <- lapply(seq(nrow(df)),function(i) expand.grid(df[i,1],halfway[[i]]))
df2 <- do.call(rbind,threequarterway)
最后,如David Robinson的回答中所述,消除NA争议:
df2 = df2[!is.na(df2[,2]),]
(David的回答是在我键入此内容时出现的,可能是一种更好的方法,但我想您可能想知道扩展.grid
)concat.split.multiple
从我的“splitstackshape”包中可以选择一步执行拆分和重塑,只剩下一件事:删除带有NA
值的行:
library(splitstackshape)
out <- concat.split.multiple(df, "vars", ",", direction = "long")
out[complete.cases(out), ]
# id var2 time vars
# 1 X1 1 1 foo
# 2 X23 2 1 world
# 4 X1 1 2 bar
# 7 X1 1 3 hello
库(splitstackshape)
outconcat.split。我的“splitstackshape”软件包中的多个
可以选择一步执行拆分和重塑,只剩下删除带有NA
值的行:
library(splitstackshape)
out <- concat.split.multiple(df, "vars", ",", direction = "long")
out[complete.cases(out), ]
# id var2 time vars
# 1 X1 1 1 foo
# 2 X23 2 1 world
# 4 X1 1 2 bar
# 7 X1 1 3 hello
库(splitstackshape)
谢谢,我得查一下数据表。更多信息!谢谢,我要查看数据表包更多!