跳轉到內容

R 程式設計/資料框操作

來自 Wikibooks,開放世界中的開放書籍

在本節中,我們將介紹如何讀取、管理和清理資料框的方法。

在 R 中,資料框是相同長度的向量列表。它們不必是相同型別。例如,您可以將邏輯、字元和數值向量組合在一個數據框中。

讀取和儲存資料

[編輯 | 編輯原始碼]

如果資料已經以 R 格式(.Rda.Rdata)存在,您可以使用 load() 將它們載入到記憶體中。您可以使用 save() 將資料儲存到 R 格式。

load("mydata.Rda")
save(list='mydata',file="mydata.Rda")

示例資料集

[編輯 | 編輯原始碼]
  • 大多數包都包含示例資料集,用於測試函式。
  • data() 函式不帶引數會顯示所有已載入包中所有示例資料集的列表。
  • 如果您想將它們載入到記憶體中,只需使用 data 函式並將資料集名稱作為引數傳入即可。
  • str_data()sfsmisc)會顯示包中所有資料集的結構。
> data() # lists all the datasets in all the packages in memory
> data(package="datasets") # lists all the datasets in the "datasets" package
> data(Orange) # loads the orange dataset in memory
> ?Orange # Help for the "Orange" Datasets
> str_data("datasets") # gives the structure of all the datasets in the datasets package.
  • 一些包包含大量資料集。
    • datasets
    • AER[1] 包含計量經濟學一些重要教科書的複製資料集。
    • EcDat[2] 包含《應用計量經濟學雜誌》、《商業與經濟統計學雜誌》等的複製檔案。

構建您自己的資料框

[編輯 | 編輯原始碼]

可以使用向量建立資料框。

N <- 100
u <- rnorm(N)
x1 <- rnorm(N)
x2 <- rnorm(N)
y <- 1 + x1 + x2 + u
mydat <- data.frame(y,x1,x2)

R 擁有類似電子表格的資料編輯器。可以使用它將資料輸入電子表格。

mydat <- edit(data.frame())

從剪貼簿讀取表格

> mydat <- read.table("clipboard")

還可以使用 `gsource()`(**Zelig**)在程式碼中讀取以空格分隔的表格。以下是使用 Yule 1899 資料的示例。[3]

mydat <- gsource(var.names = "id union pauperism out old  pop", 
variables = "
1 Kensington 27 5 104 136
2 Paddington  47 12 115 111
3 Fulham 31 21 85 174
")

可以更改資料框的列名。

c1 <- c('A','B','C')
c2 <- c('Alpha','Bravo','Charlie')
c3 <- c('1','2','3')
mydf <- data.frame(c1,c2,c3)
colnames(mydf) <- c('ColName1','ColName2','ColName3')

描述資料框

[編輯 | 編輯原始碼]

有多種方法可以檢查資料框,例如

  • `str(df)` 提供資料的簡要描述
  • `names(df)` 提供每個變數的名稱
  • `summary(df)` 提供每個變數的一些基本摘要統計資訊
  • `head(df)` 顯示前幾行
  • `tail(df)` 顯示最後幾行。

瀏覽資料

[編輯 | 編輯原始碼]
  • 可以使用 `View()` 在電子表格中瀏覽資料。根據作業系統,此選項並非始終可用,並且結果也不盡相同。
  • 可以使用 `head()` 列印前幾行,使用 `tail()` 列印最後幾行。
View(mydata)
head(mydata, n = 20) # n = 20 means  that the first 20 lines are printed in the R console
  • RStudio 擁有一個不錯的 資料瀏覽器 (`View(mydata)`)。
  • RKward 也擁有一個不錯的 資料瀏覽器
  • Paul Murrell 正在開發 **rdataviewer** 包 (pdf).

繫結行或列

[編輯 | 編輯原始碼]

在處理資料框時,大多數情況下會更改資料,其中一項常見操作是新增列或行,從而增加資料框的維度。有多種方法可以實現,但最簡單的方法是 `cbind()` 和 `rbind()`,它們是 **base** 包的一部分。

mydata <- cbind(mydata, newVector)
mydata <- rbind(mydata, newVector)

請記住,newVector 的長度應與要附加其到的資料框一側的長度匹配。例如,在 `cbind()` 命令中,以下語句應為 TRUE

dim(mydata)[1]==length(newVector)

要檢視更多示例,可以隨時執行 `?base::cbind` 和 `?base::rbind`。

附加資料

[編輯 | 編輯原始碼]

R 相比於 Stata 的一大優勢是可以同時處理多個數據集。只需要指定資料集名稱,並在每個變數名前面新增一個“$”符號(例如 `mydat1$var1` 和 `mydat2$var1`)。如果只處理一個數據集,並且不想每次都將資料集名稱作為字首新增到每個變數,可以使用 `attach()`。

mydata$var1
attach(mydata)
var1
detach(mydata)

檢測重複項

[編輯 | 編輯原始碼]

在清理資料集時,經常需要檢查資料中是否存在重複的資訊。R 提供了一些函式來檢測重複項。

  • `duplicated()` 會查詢重複元素並返回邏輯向量。可以使用 `table()` 對該向量進行彙總。
  • `Duplicated()`(**sfsmisc**)對該命令進行了泛化。`Duplicated()` 僅將唯一值標記為“NA”。
  • `remove.dup.rows()`(**cwhmisc**)。
  • `unique()` 僅保留資料集中唯一的行。
  • `distinct()`(**dplyr**)僅保留資料集中唯一的/不同的行。


library("Zelig")
mydat <- gsource(
variables = "
1 1 1 1
1 1 1 1
1 2 3 4
1 2 3 4
1 2 2 2
1 2 3 2")
unique(mydat) # keep unique rows
library(cwhmisc)
remove.dup.rows(mydat) # similar to unique()
table(duplicated(mydat)) # table duplicated lines
mydat$dups <- duplicated(mydat) # add a logical variable for duplicates

建立和刪除變數

[編輯 | 編輯原始碼]

要建立新變數

mydata$newvar <- oldvar

如果要刪除資料集中某個變數,可以將 NULL 指定給該變數

# Delete the x variable in the df data frame.
df$x <- NULL

重新命名變數

[編輯 | 編輯原始碼]
  • 可以透過重新定義資料框的名稱向量來重新命名變數。
  • **reshape** 包中還提供了 `rename()` 函式。
df <- data.frame(x = 1:10, y = 21:30)
names(df)
names(df) <- c("toto","tata")
names(df)
names(df)[2] <- "titi"
names(df)

建立資料子集

[編輯 | 編輯原始碼]

可以使用 `subset()` 對資料進行子集化。第一個引數是資料集名稱,第二個引數是邏輯條件,用於指定要包含在新資料集中哪些行,最後一個引數是要包含在新資料集中哪些變數的列表。

在以下示例中,我們將生成一個虛假資料集,並使用 `subset()` 命令選擇感興趣的行和列。我們選擇 `x1 > 0` 且 `x2 < 0` 的行,並將 `x1` 和 `x2` 作為變數保留。

N <- 100
x1 <- rnorm(N)
x2 <- 1 + rnorm(N) + x1
x3 <- rnorm(N) + x2
mydat <- data.frame(x1,x2,x3)
subset(x = mydat, subset = x1 > 0 & x2 < 0, select = c(x1,x2))
subset(x = mydat, subset = x1 > 0 & x2 < 0, select = - x3) # the same.

還可以使用 `select` 選項重新排列列。

subset(x = mydat, subset = x1 > 0 & x2 < 0, select = c(x1,x2))
subset(x = mydat, subset = x1 > 0 & x2 < 0, select = c(x2,x1))

排序和排列

[編輯 | 編輯原始碼]
  • order()
mydat[order(var1,var2),]

假設要隨機化資料集中順序。只需要從均勻分佈生成一個向量,並根據該向量進行排序。

df[order(runif(nrow(df))),]

檢測缺失值

[編輯 | 編輯原始碼]
  • `is.na()` 返回一個邏輯向量,如果資料集中任何變數缺失則為 TRUE,否則為 FALSE。
  • `complete.cases()` 返回一個邏輯向量,如果所有情況都完整則為 TRUE,否則為 FALSE。
> table(complete.cases(df))

重塑資料框

[編輯 | 編輯原始碼]

如果處理面板資料,則此主題很重要。 面板資料 可以儲存在寬格式中,每個單位一個觀測值,每個時間段一個變數;也可以儲存在長格式中,每個單位和時間段一個觀測值。`reshape()` 將資料集重塑為寬格式或長格式。

> country <- c("'Angola'","'UK'","'France'")
> gdp.1960 <- c(1,2,3)
> gdp.1970 <- c(2,4,6)
> mydat <- data.frame(country,gdp.1960,gdp.1970)
> mydat # wide format
  country gdp.1960 gdp.1970
1  Angola       1       2
2      UK       2       4
3  France       3       6
> reshape( data = mydat, varying = list(2:3) , v.names = "gdp", direction = "long") # long format
    country time gdp id
1.1  Angola    1   1  1
2.1      UK    1   2  2
3.1  France    1   3  3
1.2  Angola    2   2  1
2.2      UK    2   4  2
3.2  France    2   6  3
  • `varying` 給出隨時間變化的列的編號
  • `v.names` 給出隨時間變化的變數的字首
  • `direction` 給出方向,可以是“long”或“wide”。
  • 另請參閱
    • `reShape()`(**Hmisc**)
    • 參閱 Hadley Wickham 的 **reshape** 包[4]
    • 參閱 Duncan Murdoch 的 **tables** 包 [5]
[編輯 | 編輯原始碼]

擴充套件資料集

[編輯 | 編輯原始碼]

有時我們需要在資料集中複製一些行。例如,如果我們想生成一個具有面板資料結構的假資料集。在這種情況下,我們將首先生成時間不變變數,然後將每行復制一個給定的標量以建立隨時間變化的變數。

可以使用epicalc包中的expand()函式(由於此包不再存在,因此在[1]中給出了擴充套件的選項)。這將使每行乘以給定數字。

N <- 1000
T <- 5
wide <- data.frame(id = 1:N,f = rnorm(N),  rep = T)
library("epicalc")
long <- expand(wide,index.var = "rep")
long$time <- rep(1:T,N)

我們也可以使用自己動手解決方案或建立自己的函式。這個想法很簡單。我們建立一個向量,該向量為每行提供應複製的次數(在以下示例中為dups)。然後我們使用rep()函式建立一個向量,該向量根據我們的需要重複行號。最後一步建立了一個新的資料集,它根據所需模式重複行。

expand <- function(df,dups){
	df$dups <- dups
	pattern <- rep(1:nrow(df), times=df$dups)
	df2 <- df[pattern,]
	index <- function(x){
		1:length(x)
		}
	df2$year <- unlist(tapply(df2$dups, df2$id, index))
	df2$dups <- NULL 
	return(df2)
	}

df <- data.frame(x = rnorm(3), id = 1:3)
dups = c(3,1,2)
expand(df,dups)

合併資料幀

[編輯 | 編輯原始碼]

合併資料可能非常混亂,尤其是在多次合併的情況下。這是一個簡單的例子

我們有一個描述作者的表格

> authors <- data.frame(
+     surname = I(c("Tukey", "Venables", "Tierney", "Ripley", "McNeil")),
+     nationality = c("US", "Australia", "US", "UK", "Australia"),
+     deceased = c("yes", rep("no", 4)))
> authors
   surname nationality deceased
1    Tukey          US      yes
2 Venables   Australia       no
3  Tierney          US       no
4   Ripley          UK       no
5   McNeil   Australia       no

還有一個描述書籍的表格

> books <- data.frame(
+     name = I(c("Tukey", "Venables", "Tierney",
+              "Ripley", "Ripley", "McNeil", "R Core")),
+     title = c("Exploratory Data Analysis",
+               "Modern Applied Statistics ...",
+               "LISP-STAT",
+               "Spatial Statistics", "Stochastic Simulation",
+               "Interactive Data Analysis",
+               "An Introduction to R"),
+     other.author = c(NA, "Ripley", NA, NA, NA, NA,
+                      "Venables & Smith"))
> books
      name                         title     other.author
1    Tukey     Exploratory Data Analysis             <NA>
2 Venables Modern Applied Statistics ...           Ripley
3  Tierney                     LISP-STAT             <NA>
4   Ripley            Spatial Statistics             <NA>
5   Ripley         Stochastic Simulation             <NA>
6   McNeil     Interactive Data Analysis             <NA>
7   R Core          An Introduction to R Venables & Smith

我們想根據作者姓名(第一個資料集中為“surname”,第二個資料集中為“name”)合併“books”和“authors”表。我們使用merge()命令。我們指定第一個和第二個資料集的名稱,然後透過by.x和by.y指定兩個資料集中的識別符號。all.x和all.y指定是否要保留第一個和第二個資料集的所有觀察結果。在這種情況下,我們希望保留來自“books”資料集的所有觀察結果,但我們只保留與“books”資料集中的觀察結果匹配的來自“author”資料集的觀察結果。

> final <- merge(books, authors, by.x = "name", by.y = "surname", sort=F,all.x=T,all.y=F)
> final
      name                         title     other.author nationality deceased
1    Tukey     Exploratory Data Analysis             <NA>          US      yes
2 Venables Modern Applied Statistics ...           Ripley   Australia       no
3  Tierney                     LISP-STAT             <NA>          US       no
4   Ripley            Spatial Statistics             <NA>          UK       no
5   Ripley         Stochastic Simulation             <NA>          UK       no
6   McNeil     Interactive Data Analysis             <NA>   Australia       no
7   R Core          An Introduction to R Venables & Smith        <NA>     <NA>

也可以合併兩個資料幀物件,同時保留兩個合併物件之一的行順序。[6]

參考文獻

[編輯 | 編輯原始碼]
  1. AER 包 http://cran.r-project.org/web/packages/AER/index.html
  2. EcDat 包 http://cran.r-project.org/web/packages/Ecdat/index.html
  3. “對英國貧困變化原因的調查,主要是在過去兩個人口普查之間十年(第一部分)” - GU Yule - 英國皇家統計學會雜誌,1899 年 6 月,第 283 頁
  4. 使用 reshape 包重塑資料:http://www.jstatsoft.org/v21/i12
  5. tables 包的說明:http://cran.r-project.org/web/packages/tables/vignettes/tables.pdf
  6. 合併資料幀同時保留行順序
  7. R 資料手冊 http://cran.r-project.org/doc/manuals/R-data.html
  8. Paul Murrell 資料技術入門 http://www.stat.auckland.ac.nz/~paul/ItDT/


前一頁:隨機數生成 索引 下一頁:匯入和匯出資料
華夏公益教科書