我有以下类型的表格:
经济特区 | 班级 | 瓦尔 |
---|---|---|
1_1_1 | 1 | 2 |
1_1_1 | 5 | 2 |
1_1_2 | 5 | 2 |
1_1_3 | 1 | 1 |
1_1_3 | 5 | 2 |
1_1_4 | 1 | 1 |
1_1_5 | 2 | 1 |
1_2_1 | 1 | 2 |
1_2_1 | 5 | 2 |
为了将“Class”列分散到多个新列中,从“Val”列中获取价值,我使用了pivot_wider,一切顺利。我输入了这个代码:
pivot_wider(names_from = Class, values_from = Val, names_sort=T, values_fill = list(n = 0))
获得这样的结果:
塞兹 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|
1_1_1 | 2 | 0 | 0 | 0 | 2 | 0 | 0 |
1_1_2 | 0 | 0 | 0 | 0 | 2 | 0 | 0 |
1_1_3 | 1 | 0 | 0 | 0 | 2 | 0 | 0 |
不幸的是,我必须使用外部计算机,其中只有基本的 R 包,并且请求附加包的时间并不短。
我尝试使用这个解决方案:
newdata <- xtabs(dat$Val ~ dat$Sez + dat$Class)
但它给了我每行的频率分布:
经济特区 | 班级 | 频率 |
---|---|---|
1_1_1 | 1 | 2 |
1_1_2 | 1 | 0 |
1_1_3 | 1 | 1 |
1_1_4 | 1 | 1 |
1_1_5 | 1 | 0 |
1_2_1 | 1 | 1 |
我正在寻找一种具有 R 基本功能的解决方案,它为我提供了一个与使用ivot_wider 时使用的对象相同的对象。
我们将“类”创建为
factor
并使用 xtabs
df1$Class <- factor(df1$Class, levels = 1:7)
xtabs(Val ~ SEZ + Class, df1)
-输出
Class
SEZ 1 2 3 4 5 6 7
1_1_1 2 0 0 0 2 0 0
1_1_2 0 0 0 0 2 0 0
1_1_3 1 0 0 0 2 0 0
1_1_4 1 0 0 0 0 0 0
1_1_5 0 1 0 0 0 0 0
1_2_1 2 0 0 0 2 0 0
如果我们需要
data.frame
输出
out <- as.data.frame.matrix( xtabs(Val ~ SEZ + Class, df1))
out$SEZ <- row.names(out)
row.names(out) <- NULL
df1 <- structure(list(SEZ = c("1_1_1", "1_1_1", "1_1_2", "1_1_3", "1_1_3",
"1_1_4", "1_1_5", "1_2_1", "1_2_1"), Class = c(1L, 5L, 5L, 1L,
5L, 1L, 2L, 1L, 5L), Val = c(2L, 2L, 2L, 1L, 2L, 1L, 1L, 2L,
2L)), row.names = c(NA, -9L), class = "data.frame")
另一个基本 R 选项使用
reshape
+ merge
reshape(
merge(df,
expand.grid(
SEZ = unique(df$SEZ),
Class = 1:7
),
all = TRUE
),
direction = "wide",
idvar = "SEZ",
timevar = "Class"
)
给予
SEZ Val.1 Val.2 Val.3 Val.4 Val.5 Val.6 Val.7
1 1_1_1 2 NA NA NA 2 NA NA
8 1_1_2 NA NA NA NA 2 NA NA
15 1_1_3 1 NA NA NA 2 NA NA
22 1_1_4 1 NA NA NA NA NA NA
29 1_1_5 NA 1 NA NA NA NA NA
36 1_2_1 2 NA NA NA 2 NA NA
当“值”列包含整数时会发生什么?
我尝试将@akran解决方案(上面发布的)应用于此表(偶然在“值”列中使用字符串而不是整数
"1_1_4", "1_1_5", "1_2_1", "1_2_1"), Class = c(1L, 5L, 5L, 1L,
5L, 1L, 2L, 1L, 5L), Val = c(2L, 2L, 2L, 1L, 2L, 1L, 1L, 2L,
2L)), row.names = c(NA, -9L), class = "data.frame")
运行此命令会导致错误:
xtabs(Val ~ SEZ + Class, df1)
我们需要将输出列“Val”转换为数字,然后将其返回到文本。 此脚本完成工作(R 版本 4.3.1 (2023-06-16) 和 dplyr 1.1.2):
# create list to translate
list_mapTclass <- seq(1:length(unique(df1$Val)))
print(length(list_mapTclass))
names(list_mapTclass) <-unique(df1$Val)
df1$idxTClass <- unlist(sapply(df1$Val, function(x) list_mapTclass[[x]] ))
wide_df_matrix <-xtabs(idxTClass ~ SEZ + idxTClass, df1)
#print(list_mapTclassInverted[1:3])
#--- add subid
wide_df0 <- as.data.frame.matrix( wide_df_matrix) %>%
setNames(paste0('col_', names(.))) #%>%
# reconvert values into the therapyclass content
# inverted list:
list_mapTclassInverted <- as.list(setNames(names(list_mapTclass), list_mapTclass))
list_mapTclassInverted[['0']] <- 'Unknown'
# Next piece of code is to go through the full table and convert all the integers into their text
### VERY USEFUL! (Thanks to: @Martin Morgan - https://stackoverflow.com/questions/7547597/dictionary-style-replace-multiple-items )
wide_df0[] <- list_mapTclassInverted[unlist(wide_df0)]
## convert to a dataframe
wide_df0$SEZ <- row.names(wide_df0)
row.names(wide_df0) <- NULL
我会写另一篇关于这个问题的文章,以防这篇文章与问题完全匹配。 希望这可以帮助! 有时在 R 基础上做事情很耗时,但正如问题中提到的,当您必须使用没有更新的技术并且您不是 IT 管理员时,没有其他方法(特别是如果您必须在明天之前交付!)。