需要重组数据
need to reorganize data
我是 R 的新手,有一个数据格式问题。
我需要转换这个:
Poly Tran Strat Surv MALLP MALLS MALLG MALLF GADWP GADWS GADWG GADWF
AL 1 M y 1 2 0 0 1 4 0 0
ARL 1 M y 0 0 0 0 0 0 20 0
AM 1 M y 0 0 0 0 0 0 0 0
AM 2 M y 1 0 0 0 0 0 0 5
对此:
Poly Tran Strat Surv Spp Num Status
AL 1 M y mall 1 p
AL 1 M y mall 2 s
AL 1 M y gadw 1 p
AL 1 M y gadw 4 s
ARL 1 M y gadw 20 g
AM 2 M y mall 1 p
AM 2 M y gadw 5 f
我需要一些帮助!
谢谢。
使用 dplyr
和 tidyr
你可以:
library(tidyr)
library(dplyr)
df %>% gather(Spp, Num, -Poly, -Tran, -Strat, -Surv) %>%
mutate(Status = tolower(substr(Spp, 5, 5)),
Spp = tolower(substr(Spp, 1, 4))) %>%
filter(!Num == 0) %>%
arrange(Tran)
给出:
# Poly Tran Strat Surv Spp Num Status
#1 AL 1 M y mall 1 p
#2 AL 1 M y mall 2 s
#3 AL 1 M y gadw 1 p
#4 AL 1 M y gadw 4 s
#5 ARL 1 M y gadw 20 g
#6 AM 2 M y mall 1 p
#7 AM 2 M y gadw 5 f
使用基础 R 的解决方案(reshape2::melt
除外):
dat2 <- reshape2::melt(dat, id.vars=c("Poly","Tran","Strat","Surv"))
dat2 <- subset(dat2, subset = value > 0)
dat2$variable <- as.character(dat2$variable)
dat2$Status <- with(dat2, substr(tolower(variable), nchar(variable), nchar(variable)))
dat2$variable <- with(dat2, substr(tolower(variable), 1, nchar(variable)-1))
dat2 <- dat2[order(dat2$Tran),]
colnames(dat2) <- c("Poly", "Tran", "Strat", "Surv", "Spp", "Num", "Status")
rownames(dat2) <- NULL
结果
> dat2
Poly Tran Strat Surv Spp Num Status
1 AL 1 M y mall 1 p
2 AL 1 M y mall 2 s
3 AL 1 M y gadw 1 p
4 AL 1 M y gadw 4 s
5 ARL 1 M y gadw 20 g
6 AM 2 M y mall 1 p
7 AM 2 M y gadw 5 f
数据
dat <- read.csv(text = "Poly,Tran,Strat,Surv,MALLP,MALLS,MALLG,MALLF,GADWP,GADWS,GADWG,GADWF
AL,1,M,y,1,2,0,0,1,4,0,0
ARL,1,M,y,0,0,0,0,0,0,20,0
AM,1,M,y,0,0,0,0,0,0,0,0
AM,2,M,y,1,0,0,0,0,0,0,5")
为了好玩,这里有一个基本的 R 方法。我用 NA
替换了“0”,这样 na.omit
就可以在 stack
值之后用于 "shrink" 数据集。从那里开始,需要一些基本的 gsub
bing 来获得 "spp" 和 "status" 值。
within(na.omit(
cbind(dat[1:4],
stack(replace(dat[-c(1:4)], dat[-c(1:4)] == 0, NA)))), {
ind <- tolower(ind)
spp <- gsub("(mall|gadw).*", "\1", ind)
status <- gsub("mall|gadw", "", ind)
rm(ind)
})
# Poly Tran Strat Surv values status spp
# 1 AL 1 M y 1 p mall
# 4 AM 2 M y 1 p mall
# 5 AL 1 M y 2 s mall
# 17 AL 1 M y 1 p gadw
# 21 AL 1 M y 4 s gadw
# 26 ARL 1 M y 20 g gadw
# 32 AM 2 M y 5 f gadw
排序非常简单,如 Dominic 和 Steven 的回答所示。
这里使用 data.table
:
dt.m = melt(dt, id=1:4, variable.name="Spp", value.name="Num")[Num != 0L]
dt.m[, c("Spp", "Status") := list(substring(Spp, 1, 4), substring(Spp, 5, 5))]
或者使用 read.fwf
:
dt.m = melt(dt, id=1:4, variable.name="Spp", value.name="Num", variable.factor = FALSE)
dt.m[Num != 0L][, c("Spp", "Status") := read.fwf(textConnection(Spp), widths=c(4,1))]
我是 R 的新手,有一个数据格式问题。 我需要转换这个:
Poly Tran Strat Surv MALLP MALLS MALLG MALLF GADWP GADWS GADWG GADWF
AL 1 M y 1 2 0 0 1 4 0 0
ARL 1 M y 0 0 0 0 0 0 20 0
AM 1 M y 0 0 0 0 0 0 0 0
AM 2 M y 1 0 0 0 0 0 0 5
对此:
Poly Tran Strat Surv Spp Num Status
AL 1 M y mall 1 p
AL 1 M y mall 2 s
AL 1 M y gadw 1 p
AL 1 M y gadw 4 s
ARL 1 M y gadw 20 g
AM 2 M y mall 1 p
AM 2 M y gadw 5 f
我需要一些帮助!
谢谢。
使用 dplyr
和 tidyr
你可以:
library(tidyr)
library(dplyr)
df %>% gather(Spp, Num, -Poly, -Tran, -Strat, -Surv) %>%
mutate(Status = tolower(substr(Spp, 5, 5)),
Spp = tolower(substr(Spp, 1, 4))) %>%
filter(!Num == 0) %>%
arrange(Tran)
给出:
# Poly Tran Strat Surv Spp Num Status
#1 AL 1 M y mall 1 p
#2 AL 1 M y mall 2 s
#3 AL 1 M y gadw 1 p
#4 AL 1 M y gadw 4 s
#5 ARL 1 M y gadw 20 g
#6 AM 2 M y mall 1 p
#7 AM 2 M y gadw 5 f
使用基础 R 的解决方案(reshape2::melt
除外):
dat2 <- reshape2::melt(dat, id.vars=c("Poly","Tran","Strat","Surv"))
dat2 <- subset(dat2, subset = value > 0)
dat2$variable <- as.character(dat2$variable)
dat2$Status <- with(dat2, substr(tolower(variable), nchar(variable), nchar(variable)))
dat2$variable <- with(dat2, substr(tolower(variable), 1, nchar(variable)-1))
dat2 <- dat2[order(dat2$Tran),]
colnames(dat2) <- c("Poly", "Tran", "Strat", "Surv", "Spp", "Num", "Status")
rownames(dat2) <- NULL
结果
> dat2
Poly Tran Strat Surv Spp Num Status
1 AL 1 M y mall 1 p
2 AL 1 M y mall 2 s
3 AL 1 M y gadw 1 p
4 AL 1 M y gadw 4 s
5 ARL 1 M y gadw 20 g
6 AM 2 M y mall 1 p
7 AM 2 M y gadw 5 f
数据
dat <- read.csv(text = "Poly,Tran,Strat,Surv,MALLP,MALLS,MALLG,MALLF,GADWP,GADWS,GADWG,GADWF
AL,1,M,y,1,2,0,0,1,4,0,0
ARL,1,M,y,0,0,0,0,0,0,20,0
AM,1,M,y,0,0,0,0,0,0,0,0
AM,2,M,y,1,0,0,0,0,0,0,5")
为了好玩,这里有一个基本的 R 方法。我用 NA
替换了“0”,这样 na.omit
就可以在 stack
值之后用于 "shrink" 数据集。从那里开始,需要一些基本的 gsub
bing 来获得 "spp" 和 "status" 值。
within(na.omit(
cbind(dat[1:4],
stack(replace(dat[-c(1:4)], dat[-c(1:4)] == 0, NA)))), {
ind <- tolower(ind)
spp <- gsub("(mall|gadw).*", "\1", ind)
status <- gsub("mall|gadw", "", ind)
rm(ind)
})
# Poly Tran Strat Surv values status spp
# 1 AL 1 M y 1 p mall
# 4 AM 2 M y 1 p mall
# 5 AL 1 M y 2 s mall
# 17 AL 1 M y 1 p gadw
# 21 AL 1 M y 4 s gadw
# 26 ARL 1 M y 20 g gadw
# 32 AM 2 M y 5 f gadw
排序非常简单,如 Dominic 和 Steven 的回答所示。
这里使用 data.table
:
dt.m = melt(dt, id=1:4, variable.name="Spp", value.name="Num")[Num != 0L]
dt.m[, c("Spp", "Status") := list(substring(Spp, 1, 4), substring(Spp, 5, 5))]
或者使用 read.fwf
:
dt.m = melt(dt, id=1:4, variable.name="Spp", value.name="Num", variable.factor = FALSE)
dt.m[Num != 0L][, c("Spp", "Status") := read.fwf(textConnection(Spp), widths=c(4,1))]