小技巧--對(duì)常用的三種數(shù)據(jù)類型進(jìn)行轉(zhuǎn)換(數(shù)值型、字符型和因子型)。為什么要了解數(shù)據(jù)結(jié)構(gòu)之間的差異和做對(duì)應(yīng)轉(zhuǎn)換呢?通常在畫(huà)圖和做分析時(shí),不同情況對(duì)數(shù)據(jù)類型需求不一樣,特別是新手在學(xué)習(xí)代碼的時(shí)候,如果不清楚數(shù)據(jù)結(jié)構(gòu)很容易造成錯(cuò)誤。針對(duì)不同情況,根據(jù)自己的需求調(diào)整對(duì)應(yīng)的數(shù)據(jù)類型,這樣有助于我們更好地學(xué)習(xí)和運(yùn)行code。通常所有的數(shù)據(jù)我們統(tǒng)稱為向量,針對(duì)不同數(shù)據(jù)集結(jié)構(gòu)(這里可以參考我們以前發(fā)表的推文:【R分享|實(shí)戰(zhàn)】 新手福利~認(rèn)識(shí)數(shù)據(jù)集的內(nèi)在),主要可分為兩類向量。一是,原子向量;二是,遞歸向量。我們可以借助下面這張圖(黃師兄的總結(jié))來(lái)理解:也就是說(shuō),原子向量主要包括:logical,integer, double, character等類型,其中integer和double統(tǒng)稱為numeric(數(shù)值型向量)。而列表通常被稱為遞歸向量,因?yàn)樗?/span>可以包含其他列表。 不同數(shù)據(jù)類型之間的差異與轉(zhuǎn)換 針對(duì)這部分內(nèi)容,以代碼的形式給大家分享和講解,希望能幫助大家少走彎路。首先,我們先構(gòu)造數(shù)據(jù)集,并解讀數(shù)據(jù)集中不同的數(shù)據(jù)類型:# 不同數(shù)據(jù)類型之間的差異與轉(zhuǎn)換 -------------------------- # 隨機(jī)構(gòu)造數(shù)據(jù)集 year <- rep(2000:2021, 2) treatment <- rep(c("ck","treat"), each = 22) type <- factor(rep(c("a","b","c","d"), each = 11)) value1 <- sample(1:50, 44) value2 <- round(runif(44, min = 0, max = 1), 3) set.seed(111) value3 <- sample(c("1","1.5","2.5","3.5","4.5","5"), 44, replace = T) set.seed(111) value4 <- sample(c(1,1.5,2.5,3.5,4.5,5), 44, replace = T) # 打包數(shù)據(jù)集 dat <- data.frame(treatment, type, year, value1, value2, value3, value4) # 查看數(shù)據(jù)結(jié)構(gòu) str(dat) # 從查詢的結(jié)果來(lái)看,treatment這個(gè)變量是字符型-“cha”向量; # type為因子型向量(factor)w/4表示有4個(gè)因子 # year是整數(shù)-“int”數(shù)值型向量;value1與year是同樣類型的數(shù)值; # value2是數(shù)值型向量;value3是字符型;value4是與v3相同值的數(shù)值型變量。
上述code的結(jié)果:
然后,我們分別以繪圖和跑模型的方式對(duì)其差異進(jìn)行講解:# 以畫(huà)圖為例進(jìn)行不同數(shù)據(jù)類型變量的講解: library(ggplot2) ggplot(data = dat, aes(x = year, y = value1, color=treatment))+ geom_point()+ geom_line()+ labs(x="year") # 從圖來(lái)看,由于year是數(shù)值型變量,畫(huà)圖時(shí)候會(huì)默認(rèn)成連續(xù)型的所以會(huì)有間隔
# 這里我們將year改成因子型變量再對(duì)其進(jìn)行展示: ggplot(dat, aes(as.factor(year), value1, color=treatment))+ geom_point()+ # geom_line()+ geom_path(group=treatment)+ labs(x="year") # 由于對(duì)x的變量進(jìn)行了因子型轉(zhuǎn)換,這個(gè)地方也是大家比較容易出錯(cuò)的。 # 對(duì)變量進(jìn)行因子轉(zhuǎn)化后,geom_line函數(shù)不能識(shí)別分組; # 因此利用geom_path函數(shù)的分組進(jìn)行繪制。
從兩張圖來(lái)看,結(jié)果似乎差異不大,僅僅在x軸的label上出現(xiàn)了差異。圖1為數(shù)值型的x軸是連續(xù)的,默認(rèn)為數(shù)值,并不是實(shí)際的年份,所以會(huì)出現(xiàn)0.5這樣的年份表達(dá)。 如果,我們將y軸用字符型的數(shù)據(jù)進(jìn)行繪圖,會(huì)有怎么的差異:
# 如果我們使用字符型作為我們的x軸和y軸,看看結(jié)果如何; ggplot(dat, aes(treatment, value3, fill = type))+ geom_bar(stat = "identity", position = "dodge")
# 用相同的數(shù)值,但是不同的數(shù)據(jù)類型y,比較兩者差異 ggplot(dat, aes(treatment, value4, fill = type))+ geom_bar(stat = "identity", position = "dodge")
從兩個(gè)結(jié)果來(lái)看,存在明顯差異。如果是數(shù)值型向量,柱狀圖會(huì)默認(rèn)展示一個(gè)總的柱狀圖;而如果是字符型向量,可以把每一個(gè)值都看作是個(gè)體,展示所有的情況。 接下來(lái),我們從模型方面來(lái)理解,這里以最簡(jiǎn)單的線性模型為例:# 如果自變量為數(shù)值型 fit1 <- lm(value1 ~ year, data=dat) summary(fit1)
# 如果自變量為因子型 fit2 <- lm(value1~ as.factor(year), data=dat) summary(fit2)
# 如果自變量為字符型 fit3 <- lm(value1~ as.character(year), data=dat) summary(fit3)
當(dāng)自變量為數(shù)值型時(shí): 當(dāng)自變量為字符型時(shí):
從這里可以看出當(dāng)自變量為因子型或者字符型時(shí),會(huì)將每個(gè)年份都作為一個(gè)個(gè)體與因變量做擬;而數(shù)值型是一個(gè)總體。并且,需要考慮當(dāng)用其他更加復(fù)雜的模型,如果是字符型或因子型會(huì)延長(zhǎng)模型的計(jì)算時(shí)間。特別是混合效應(yīng)模型。 最后,我們可以根據(jù)自己的需要對(duì)三種數(shù)據(jù)類型之間進(jìn)行轉(zhuǎn)換:# 三種數(shù)據(jù)類型之間的轉(zhuǎn)換 ------------------------------------------------------------- # 如何將因子(factor)類型里的數(shù)值轉(zhuǎn)換對(duì)應(yīng)的數(shù)值型呢? # 有兩種方式 # 首先對(duì)year數(shù)值型變量轉(zhuǎn)化成因子型(這個(gè)只是為了做個(gè)示范,如果本身有因子型就不需要再做轉(zhuǎn)換) dat$year <- factor(dat$year) class(dat$year) # 然后再嘗試將其轉(zhuǎn)化數(shù)值 year <- as.numeric(as.character(dat$year)) class(year) # y1 <- as.numeric(levels(dat$year)[dat$year]) # class(y1) # 因子型轉(zhuǎn)數(shù)值型的思路:先轉(zhuǎn)換成字符型然后再轉(zhuǎn)換成數(shù)值型。
# 如何將字符型的數(shù)值轉(zhuǎn)換對(duì)應(yīng)的數(shù)值型? v3_num <- as.data.frame(lapply(dat$value3,as.numeric)) str(v3_num) # 我們查看結(jié)果發(fā)現(xiàn)是轉(zhuǎn)化了但是變成了1行N列的值 # 需要對(duì)其進(jìn)行轉(zhuǎn)置 # 由于轉(zhuǎn)置之后數(shù)據(jù)框變成了矩陣,用data.frame把矩陣又變回?cái)?shù)據(jù)框 # 同時(shí)在轉(zhuǎn)數(shù)據(jù)框的時(shí)候一定要加上stringsAsFactors = F v3_t <- t(v3_num) v3_t_num <- data.frame(v3_t, stringsAsFactors = F) dat$v3 <- v3_t_num$v3_t str(dat) # 最后可以看到v3的結(jié)果和value4的結(jié)果是一樣的,說(shuō)明成功了。
# 如何對(duì)字符型和因子型進(jìn)行互轉(zhuǎn)? # 將字符型轉(zhuǎn)換成因子型 value3 <- as.character(dat$value3) class(value3)
# 將因子型轉(zhuǎn)換成字符型 value3_1 <- factor(value3) class(value3_1)
|