在没有时间变量的情况下重塑数据
Reshaping data with no time var
问题:
如何从现有的数据集生成新的数据集,基本上就是从长到宽的reshape,但是稍微复杂一些。
我有大量数据,我在下面提供了一个简化版本:
id <- c(1,2,3,4,5)
job <- c(11,12,11,12,13)
sex <- c(0,1,0,1,0)
country <- c(1,2,3,2,1)
data <- data.frame(id, job, sex, country)
所需数据:
我想要一个工作及其占用者的数据集,如下所示:
在 job=11 中,我有 2 个性别==0 和 1 个出生在国家==1 和 1 个出生在国家==3
因此,新数据集将是这样的:
jobs jobs_sex0 jobs_sex1 jobs_country1 jobs_country2 jobs_country3
1 11 2 0 1 0 0
2 12 0 2 0 2 0
3 13 1 0 0 0 1
我有一种直觉,这可以通过 tapply 实现,但我不确定如何实现。
我试过了,还是不行:
tapply(occupation[sex==1],sex[sex==1], sum)
aggregate(occupation, list(sex), fun=sum)
编辑:
我认为这个 Q 不是 Transpose / reshape dataframe without "timevar" from long to wide format 的副本,因为我遇到的问题是我需要用不同的级别数重塑不同的因子变量......应用假设重复的 Q 的答案不起作用.. .
我想知道 tableone package 是否可以帮助您。考虑:
data$sex <- factor(data$sex) # note that you will have to ensure these are factors
data$country <- factor(data$country)
library(tableone)
tab1 <- CreateTableOne(vars=c("sex", "country"), strata="job", data=data)
print(tab1, showAllLevels=TRUE, test=FALSE, explain=FALSE)
# Stratified by job
# level 11 12 13
# n 2 2 1
# sex 0 2 (100.0) 0 ( 0.0) 1 (100.0)
# 1 0 ( 0.0) 2 (100.0) 0 ( 0.0)
# country 1 1 ( 50.0) 0 ( 0.0) 1 (100.0)
# 2 0 ( 0.0) 2 (100.0) 0 ( 0.0)
# 3 1 ( 50.0) 0 ( 0.0) 0 ( 0.0)
如果要进行后续处理,上面的方案就不太可行了。这是一个编码解决方案,但您必须针对每种情况对其进行调整:
out.data <- t(sapply(split(data, job), function(df){
with(df, c(table(sex), table(country))) }))
out.data <- data.frame(job=rownames(out.data), out.data)
rownames(out.data) <- NULL
colnames(out.data)[2:6] <- c(paste("sex", levels(data$sex), sep="_"),
paste("country", levels(data$country), sep="_") )
out.data
# job sex_0 sex_1 country_1 country_2 country_3
# 1 11 2 0 1 0 1
# 2 12 0 2 0 2 0
# 3 13 1 0 1 0 0
我想我找到了另一个非常简单的解决方案,在一些朋友的帮助下:)
data
id job sex country
1 1 11 2 1
2 2 12 1 2
3 3 11 2 3
4 4 12 1 2
5 5 13 2 1
data$sex <- as.factor(data$sex)
data$country <- as.factor(data$country)
agg_data <- aggregate((model.matrix(~.-1, data[,-(1:2)])), by =
list(unique.jobs = data$job), FUN=sum)
agg_data
unique.jobs sex1 sex2 country1 country2 country3
1 11 0 2 1 0 1
2 12 2 0 0 2 0
3 13 0 1 1 0 0
问题: 如何从现有的数据集生成新的数据集,基本上就是从长到宽的reshape,但是稍微复杂一些。
我有大量数据,我在下面提供了一个简化版本:
id <- c(1,2,3,4,5)
job <- c(11,12,11,12,13)
sex <- c(0,1,0,1,0)
country <- c(1,2,3,2,1)
data <- data.frame(id, job, sex, country)
所需数据: 我想要一个工作及其占用者的数据集,如下所示: 在 job=11 中,我有 2 个性别==0 和 1 个出生在国家==1 和 1 个出生在国家==3
因此,新数据集将是这样的:
jobs jobs_sex0 jobs_sex1 jobs_country1 jobs_country2 jobs_country3
1 11 2 0 1 0 0
2 12 0 2 0 2 0
3 13 1 0 0 0 1
我有一种直觉,这可以通过 tapply 实现,但我不确定如何实现。
我试过了,还是不行:
tapply(occupation[sex==1],sex[sex==1], sum)
aggregate(occupation, list(sex), fun=sum)
编辑: 我认为这个 Q 不是 Transpose / reshape dataframe without "timevar" from long to wide format 的副本,因为我遇到的问题是我需要用不同的级别数重塑不同的因子变量......应用假设重复的 Q 的答案不起作用.. .
我想知道 tableone package 是否可以帮助您。考虑:
data$sex <- factor(data$sex) # note that you will have to ensure these are factors
data$country <- factor(data$country)
library(tableone)
tab1 <- CreateTableOne(vars=c("sex", "country"), strata="job", data=data)
print(tab1, showAllLevels=TRUE, test=FALSE, explain=FALSE)
# Stratified by job
# level 11 12 13
# n 2 2 1
# sex 0 2 (100.0) 0 ( 0.0) 1 (100.0)
# 1 0 ( 0.0) 2 (100.0) 0 ( 0.0)
# country 1 1 ( 50.0) 0 ( 0.0) 1 (100.0)
# 2 0 ( 0.0) 2 (100.0) 0 ( 0.0)
# 3 1 ( 50.0) 0 ( 0.0) 0 ( 0.0)
如果要进行后续处理,上面的方案就不太可行了。这是一个编码解决方案,但您必须针对每种情况对其进行调整:
out.data <- t(sapply(split(data, job), function(df){
with(df, c(table(sex), table(country))) }))
out.data <- data.frame(job=rownames(out.data), out.data)
rownames(out.data) <- NULL
colnames(out.data)[2:6] <- c(paste("sex", levels(data$sex), sep="_"),
paste("country", levels(data$country), sep="_") )
out.data
# job sex_0 sex_1 country_1 country_2 country_3
# 1 11 2 0 1 0 1
# 2 12 0 2 0 2 0
# 3 13 1 0 1 0 0
我想我找到了另一个非常简单的解决方案,在一些朋友的帮助下:)
data
id job sex country
1 1 11 2 1
2 2 12 1 2
3 3 11 2 3
4 4 12 1 2
5 5 13 2 1
data$sex <- as.factor(data$sex)
data$country <- as.factor(data$country)
agg_data <- aggregate((model.matrix(~.-1, data[,-(1:2)])), by =
list(unique.jobs = data$job), FUN=sum)
agg_data
unique.jobs sex1 sex2 country1 country2 country3
1 11 0 2 1 0 1
2 12 2 0 0 2 0
3 13 0 1 1 0 0