我有一个大型数据框,其中多列代表不同个体的不同变量。列的名称始终以数字开头(例如1:18)。我想将df分组并为每个人创建separete dfs。这是一个例子:
x <- as.data.frame(matrix(nrow=10,ncol=18))
colnames(x) <- paste(1:18, 'col', sep="")
我的真实df的列名是个人ID,变量名和度量数的组合(我对每个变量采取了3个度量)。因此,例如,我有个人1的度量b(正文),然后在df我将有3列名为:1b1,1b2,1b3。最后我有10个不同的区域(身体,头部,尾部,尾巴,背部,侧腹,腹部,喉部,前臂,腿部)。因此,对于每个人,我有30列(10个区域x每个区域3个度量)。所以我有多个变量以不同的数字开头,我想根据它们的唯一数字进行子集化。我尝试使用grep:
partialName <- 1
df2<- x[,grep(partialName, colnames(x))]
colnames(x)
[1] "1col" "2col" "3col" "4col" "5col" "6col" "7col" "8col" "9col" "10col"
"11col" "12col" "13col" "14col" "15col" "16col" "17col" "18col"
我的问题在这里你可以看到它并没有将个体分开,因为1和10在子集中。换句话说,这会选择以1开头的所有人。 最终我想要做的就是遍布所有人(1:18),为每个人创建新的dfs。
答案 0 :(得分:1)
我认为将数据保存在一个data.frame
中是最佳选择。要么是这样,要么把它放到data.frame
的列表中。这样可以更轻松地轻松提取每个人的摘要统计信息。
首先创建一些示例数据:
df = as.data.frame(matrix(runif(50 * 100), 100, 50), stringsAsFactors = FALSE)
names_variables = c('spam', 'ham', 'shrub')
individuals = 1:100
column_names = paste(sample(individuals, 50),
sample(names_variables, 50, TRUE),
sep = '')
colnames(df) = column_names
我首先要做的是使用melt
将数据从宽格式转换为长格式。这基本上将所有列堆叠在一个大向量中,并添加一个额外的列,告诉它来自哪个列:
library(reshape2)
df_melt = melt(df)
head(df_melt)
variable value
1 85ham 0.83619111
2 85ham 0.08503596
3 85ham 0.54599402
4 85ham 0.42579376
5 85ham 0.68702319
6 85ham 0.88642715
然后我们需要将ID号与变量分开。这里的假设是变量的数字部分是单个ID,文本是变量名称:
library(dplyr)
df_melt = mutate(df_melt, individual_ID = gsub('[A-Za-z]', '', variable),
var_name = gsub('[0-9]', '', variable))
基本上删除不需要的部分字符串。现在我们可以做很多好事:
mean_per_indivdual_per_var = summarise(group_by(df_melt, individual_ID, var_name),
mean(value))
head(mean_per_indivdual_per_var)
individual_ID var_name mean(value)
1 63 spam 0.4840511
2 46 ham 0.4979884
3 20 shrub 0.5094550
4 90 ham 0.5550148
5 30 shrub 0.4233039
6 21 ham 0.4764298
答案 1 :(得分:1)
您的colnames
似乎是data.frame的标准版本,因此要获得第1列,您可以执行此操作:
df2 <- df[,1] #Where 1 can be changed to the number of column you wish.
无需按部分名称进行子集化。 虽然不建议您创建一个循环来执行此操作:
for (i in ncol(x)){
assing(paste("df",i), x[,i]) #I use paste to get a different name for each column
}
虽然@paulhiemstra解决方案避免了循环。
因此,使用新信息,您可以按照自己的意愿使用grep,但具体说明您期望的匹配数量:
df2<- x[,grep("1{30}", colnames(x))]