[英]Subset data frame based on first letters of column name
我有一個大型數據框,其中多列代表不同個體的不同變量。 列的名稱始終以數字開頭(例如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。
我認為將數據保存在一個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
您的colnames
似乎是colnames
的標准名稱,因此要獲得第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))]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.