[英]Split a single column into multiple columns based on Rows
我在 R 中有一個數據集,它由一個單列組成,其中包含我在多列中理想的變量。 單列數據框的結構是這樣的。
A1
200
250
Brand x
A2
400
300
Brand x
A4
100
320
Brand x2
我想以這樣的方式拆分此列,使其以這樣的多列框架結束(“|”純粹是為了表示列分隔符):
A1 | 200 | 250 | Brand x
A2 | 400 | 300 | Brand x1
A4 | 100 | 320 | Brand x2
我怎么能這樣做? 水平數據中最多有一個序列 - 例如:4 個變量 - A1,200, 250,Brand x。 天真的等價物是在 Excel 中復制和轉置粘貼,但對於 4 個值的預定義序列。 任何人都可以幫我解決這個問題嗎?
這是我將如何做到的:
df2 <- as.data.frame(matrix(df1[,1], byrow=TRUE, ncol = 4))
或者,等效地:
df2 <- as.data.frame(t(matrix(df1[,1],nrow = 4)))
在這兩種情況下,這都會產生所需的結果:
#> df2
# V1 V2 V3 V4
#1 A1 200 250 Brand x
#2 A2 400 300 Brand x
#3 A4 100 320 Brand x2
數據
df1 <-read.table(text="A1
200
250
'Brand x'
A2
400
300
'Brand x'
A4
100
320
'Brand x2'", header=FALSE)
這不是一個優雅的解決方案,但應該有效。
一些解釋:
前兩行應該只提供您通常通過讀取數據獲得的數據幀。
如果列中存在字符串,則 R 將在因子變量中轉換該列。 出於這個原因,我在第 3 行將其轉換回字符向量。
使用矩陣,您可以將這個向量重新排列為您想要的形狀,然后您可以將其轉換回數據幀(設置stringAsFactors=FALSE
以防止所有內容都轉換為默認值)。
但是,現在所有的變量都是字符變量。 因此,您需要適當地對變量進行編碼。
dat<-c("A1",200,250,"Brand x" ,"A2",400,0300, "Brand x", "A4",100, 320,"Brand x2")
dat<-data.frame(dat)
dat<-as.character(dat[,1])
dat<-matrix(dat, ncol = 4, byrow=TRUE)
dat<-data.frame(dat, stringsAsFactors = FALSE)
dat[] <- lapply(dat, type.convert)
> str(dat)
'data.frame': 3 obs. of 4 variables:
$ X1: Factor w/ 3 levels "A1","A2","A4": 1 2 3
$ X2: int 200 400 100
$ X3: int 250 300 320
$ X4: Factor w/ 2 levels "Brand x","Brand x2": 1 1 2
> dat
X1 X2 X3 X4
1 A1 200 250 Brand x
2 A2 400 300 Brand x
3 A4 100 320 Brand x2
這里只是一個提示 - 如果序列總是重復(即是確定性的),您可以讀取向量並更改維度,例如:
data <- c("A1","200","250","Brand x","A2","400","300","Brand x","A4","100","320","Brand x2")
dim(data) <- c(4,3)
data <- t(data) # transpose
class(data)
data.df <- as.data.frame(data)
class (data.df)
這將數據的維度更改為矩陣(因為內部向量和矩陣存儲相同,因此維度不同)。
執行時會打印
> class(data)
[1] "matrix"
> class (data.df)
[1] "data.frame"
然后data.df
是一個 data.frame 對象,所以你可以在處理數據之前對數據做任何你需要做的事情(例如將列更改為數字/字符/等)。
如果它總是 4 個值,下面的循環對我有用:
df <- read.csv("df.csv", sep = ";", header = FALSE)
new.df <- data.frame()
j <- 1
i <- 1
while(i < length(df[,1])-1){
temp.df <- data.frame()
temp.df[j,1] <- df[i,1]
temp.df[j,2] <- df[i + 1, 1]
temp.df[j,3] <- df[i + 2, 1]
temp.df[j,3] <- df[i + 3, 1]
new.df <- rbind(new.df, temp.df)
j <- j + 1
i <- i + 4
}
na.omit(new.df)
它沒有完全優化,但它完成了工作! 希望對你有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.