簡體   English   中英

基於列名的第一個字母的子集數據框

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM