我认为我确实将广泛的数据转换为了很长时间,而且我已经使用了一段时间,但我最近发现出了问题。显然,代码是错误的,我似乎无法解决它。
广泛的数据很复杂,因为它包含有关何时开始他/她的第一份工作,第二份工作等的信息。我想把它变成面板数据。
因此原始数据df
如下所示:
id name gender job1 sjob1 ejob1 job2 sjob2 ejob2 job3 sjob3 ejob3
1 Jane F 100 1990 1992 103 1993 1995 104 1994 1997
2 Tom M 200 1978 1980 400 1981 1985 NA NA NA
工作号码是工作代码,表示某些工作,如管理,销售等。
以上是我所拥有的完整数据的非常简短的版本。想要的输出是:
id name gender year job
1 Jane F 1990 100
1 Jane F 1991 100
1 Jane F 1992 100
1 Jane F 1993 103
1 Jane F 1994 104
1 Jane F 1995 104
1 Jane F 1996 104
1 Jane F 1997 104
2 Tom M 1978 200
2 Tom M 1979 200
2 Tom M 1980 200
2 Tom M 1981 400
2 Tom M 1982 400
2 Tom M 1983 400
2 Tom M 1984 400
2 Tom M 1985 400
对于宽版本,我总共有大约1600个观测值。 (1600人)。我尝试了以下但没有工作:
df_long <-reshape(df,
varying=c("job1", "job2", "job3"),
v.names="job",
timevar="year",
times=c("sjob1", "sjob2", "sjob3"),
direction = "long")
这实际上成功地按照sjob1,sjob2,sjob3(每个作业的开始年份)的顺序保存了作业代码但是没有在sjob1下保存年份而是仅记录了sjob1:
id name gender year job
1 Jane F sjob1 100
1 Jane F sjob2 103
1 Jane F sjob3 104
2 Tom M sjob1 200
2 Tom M sjob2 400
2 Tom M sjob3 NA
以上是我原始数据的示例,因此我也想发布原始数据:https://www.dropbox.com/s/ygbkd91ataqkwz5/origin_wide.RData
答案 0 :(得分:0)
这是使用reshape2
和plyr
的草图:
第1步:重塑一个&#34; long&#34;格式与您正在寻找的格式有些不同:
library(reshape2)
df.m <- melt(df, id.vars=c("id", "name", "gender"))
这将为您提供作业的开始和结束时间以及分类。
第2步:隔离作业ID:
df.m$job.id <- as.integer(gsub("^(.*job)([0-9]+)$", "\\2", df.m$variable))
df.m$variable <- gsub("^(.*)([0-9]+)$", "\\1", df.m$variable)
步骤3:您可以为每个人ID和工作ID计算工作分类表(以及姓名和性别):
library(plyr)
df.jc <- rename(subset(df.m, variable=="job", select=c("id", "name", "gender", "value")), variable=job)
第4步:要获得完整的结果,您需要dcast
数据才能获得更广泛的结果&#34;具有两列sjob
和ejob
的格式以及每个作业ID的每人ID一次观察。然后,您可以adply
生成一系列年份,然后将其合并回df.jc
。
我还没有对代码进行测试,也无法为最后一步提供一些东西,因为我无法轻松读取您的示例数据。如果您拥有dput
数据,那将会有很大帮助。有关更多问题,请另外提出一个更详细的问题,并提供一些代码和数据。
答案 1 :(得分:0)
您可以使用plyr
包执行此操作:
# reading the data
df <- read.table(text = "id name gender job1 sjob1 ejob1 job2 sjob2 ejob2 job3 sjob3 ejob3
1 Jane F 100 1990 1992 103 1993 1995 104 1994 1997
2 Tom M 200 1978 1980 400 1981 1985 NA NA NA", header = TRUE, strip.white = TRUE)
# needed package
require(plyr)
# transforming the data
df2 <- rbind(
ddply(df, .(id, name, gender), mutate, year = sjob1, job = job1),
ddply(df, .(id, name, gender), mutate, year = ejob1, job = job1),
ddply(df, .(id, name, gender), mutate, year = sjob2, job = job2),
ddply(df, .(id, name, gender), mutate, year = ejob2, job = job2),
ddply(df, .(id, name, gender), mutate, year = sjob3, job = job3),
ddply(df, .(id, name, gender), mutate, year = ejob3, job = job3)
)
# getting rid off NA's & ordering the dataframe by id
df2 <- na.omit(df2[order(df2$id),c(1:3,13,14)])
答案 2 :(得分:0)
我们在onetree包中使用reshape_toLong命令将数据从宽到长整形。
devtools::install_github("yikeshu0611/onetree") #install yikeshu0611
library(onetree)
df.long = reshape_toLong(data=df,
id="id",
j="new",
value.var.prefix = c("job","sjob","ejob"))
df. long
id name gender new job sjob ejob
1 1 Jane F 1 100 1990 1992
2 1 Jane F 2 103 1993 1995
3 1 Jane F 3 104 1994 1997
4 2 Tom M 1 200 1978 1980
5 2 Tom M 2 400 1981 1985
6 2 Tom M 3 NA NA NA
我们可以在数据df.long中看到,年份变量sjob和ejob是分开的,例如,我们仅获得两个数据框,并且行将它们绑定。
df.sjob=df.long[,-7] #data with sjob
colnames(df.sjob)[6]="year" #change sjob to year
df.sjob
id name gender new job year
1 1 Jane F 1 100 1990
2 1 Jane F 2 103 1993
3 1 Jane F 3 104 1994
4 2 Tom M 1 200 1978
5 2 Tom M 2 400 1981
6 2 Tom M 3 NA NA
df.ejob=df.long[,-6] #data with sjob
colnames(df.ejob)[6]="year" #change sjob to year
id name gender new job year
1 1 Jane F 1 100 1992
2 1 Jane F 2 103 1995
3 1 Jane F 3 104 1997
4 2 Tom M 1 200 1980
5 2 Tom M 2 400 1985
6 2 Tom M 3 NA NA
rbind df.sjob和df.ejob
rbind(df.sjob,df.ejob)
id name gender new job year
1 1 Jane F 1 100 1990
2 1 Jane F 2 103 1993
3 1 Jane F 3 104 1994
4 2 Tom M 1 200 1978
5 2 Tom M 2 400 1981
6 2 Tom M 3 NA NA
7 1 Jane F 1 100 1992
8 1 Jane F 2 103 1995
9 1 Jane F 3 104 1997
10 2 Tom M 1 200 1980
11 2 Tom M 2 400 1985
12 2 Tom M 3 NA NA