R 使用指示向量将宽形状改为长形状
我有这样一个数据框:R 使用指示向量将宽形状改为长形状,r,dplyr,reshape,tidyr,R,Dplyr,Reshape,Tidyr,我有这样一个数据框: df <- data.frame(v11=rnorm(1), v12=rnorm(1), v21=rnorm(1), v31=rnorm(1), v41=rnorm(1), v42=rnorm(1), v43=rnorm(1)) v11 v21 v31 v41 v12 NA NA v42 NA NA NA v43 某些列是对同一主题的重复观察,例如v11和v12是来自同一主题的两个观察。 v21和v32仅为单一观察结果v4x有三个观察结果 我
df <- data.frame(v11=rnorm(1), v12=rnorm(1), v21=rnorm(1), v31=rnorm(1), v41=rnorm(1), v42=rnorm(1), v43=rnorm(1))
v11 v21 v31 v41
v12 NA NA v42
NA NA NA v43
某些列是对同一主题的重复观察,例如v11
和v12
是来自同一主题的两个观察。
v21
和v32
仅为单一观察结果<代码>v4x有三个观察结果
我想重塑数据帧,使其如下所示:
df <- data.frame(v11=rnorm(1), v12=rnorm(1), v21=rnorm(1), v31=rnorm(1), v41=rnorm(1), v42=rnorm(1), v43=rnorm(1))
v11 v21 v31 v41
v12 NA NA v42
NA NA NA v43
注意,它应该包含变量的值,而不是它们的名称
我有一个指示向量,用于标记观察结果:
v <- c(1, 2, 1, 1, 1, 2, 3)
v这里有一个使用dplyr
+tidyr
的解决方案:
library(dplyr)
library(tidyr)
v <- c(1,2,1,1,1,2,3)
df %>%
gather(var, value) %>%
mutate(row_num = v,
col_num = paste0("v", cumsum(v==1))) %>%
select(-var) %>%
spread(col_num, value)
数据:
row_num v1 v2 v3 v4
1 1 -0.5604756 1.558708 0.07050839 0.1292877
2 2 -0.2301775 NA NA 1.7150650
3 3 NA NA NA 0.4609162
df = structure(list(v11 = -0.560475646552213, v12 = -0.23017748948328,
v21 = 1.55870831414912, v32 = 0.070508391424576, v41 = 0.129287735160946,
v42 = 1.71506498688328, v43 = 0.460916205989202), .Names = c("v11",
"v12", "v21", "v32", "v41", "v42", "v43"), row.names = c(NA,
-1L), class = "data.frame")
下面是一个使用dplyr
+tidyr
的解决方案:
library(dplyr)
library(tidyr)
v <- c(1,2,1,1,1,2,3)
df %>%
gather(var, value) %>%
mutate(row_num = v,
col_num = paste0("v", cumsum(v==1))) %>%
select(-var) %>%
spread(col_num, value)
数据:
row_num v1 v2 v3 v4
1 1 -0.5604756 1.558708 0.07050839 0.1292877
2 2 -0.2301775 NA NA 1.7150650
3 3 NA NA NA 0.4609162
df = structure(list(v11 = -0.560475646552213, v12 = -0.23017748948328,
v21 = 1.55870831414912, v32 = 0.070508391424576, v41 = 0.129287735160946,
v42 = 1.71506498688328, v43 = 0.460916205989202), .Names = c("v11",
"v12", "v21", "v32", "v41", "v42", "v43"), row.names = c(NA,
-1L), class = "data.frame")
您还可以使用reformae2
和transform
中的melt
和dcast
执行此操作:
library(reshape2)
dcast(transform(melt(df),
rownum = substr(variable,3,3),
cols = substr(variable,1,2)),
rownum ~ cols, value.var = 'value')
结果是:
rownum v1 v2 v3 v4
1 1 1.43420148 0.7391372 -1.758605 -0.06982523
2 2 -0.07729196 NA NA 0.45190553
3 3 NA NA NA -1.95836646
数据:
set.seed(2017年)
df您也可以使用melt
和dcast
从restrape2
和transform
执行此操作:
library(reshape2)
dcast(transform(melt(df),
rownum = substr(variable,3,3),
cols = substr(variable,1,2)),
rownum ~ cols, value.var = 'value')
结果是:
rownum v1 v2 v3 v4
1 1 1.43420148 0.7391372 -1.758605 -0.06982523
2 2 -0.07729196 NA NA 0.45190553
3 3 NA NA NA -1.95836646
数据:
set.seed(2017年)
df这是baseR
中的解决方案,仅取决于对测量数据进行分组的向量v
:
首先,示例数据:
set.seed(0)
df <- data.frame(v11=rnorm(1), v12=rnorm(1), v21=rnorm(1), v31=rnorm(1), v41=rnorm(1), v42=rnorm(1), v43=rnorm(1))
# v11 v12 v21 v31 v41 v42 v43
#1 1.262954 -0.3262334 1.329799 1.272429 0.4146414 -1.53995 -0.928567
v <- c(1,2,1,1,1,2,3)
set.seed(0)
df这是baseR
中的解决方案,仅取决于对测量数据进行分组的向量v
:
首先,示例数据:
set.seed(0)
df <- data.frame(v11=rnorm(1), v12=rnorm(1), v21=rnorm(1), v31=rnorm(1), v41=rnorm(1), v42=rnorm(1), v43=rnorm(1))
# v11 v12 v21 v31 v41 v42 v43
#1 1.262954 -0.3262334 1.329799 1.272429 0.4146414 -1.53995 -0.928567
v <- c(1,2,1,1,1,2,3)
set.seed(0)
df这是使用矩阵索引的完美案例,因为您已经有了行索引
以下是如何做到这一点:
M <- matrix(NA, nrow = max(v), ncol = sum(v == 1))
M[cbind(v, cumsum(v == 1))] <- unlist(df, use.names = FALSE)
M
# [,1] [,2] [,3] [,4]
# [1,] -0.5604756 1.558708 0.07050839 0.1292877
# [2,] -0.2301775 NA NA 1.7150650
# [3,] NA NA NA 0.4609162
M这是使用矩阵索引的完美案例,因为您已经有了行索引
以下是如何做到这一点:
M <- matrix(NA, nrow = max(v), ncol = sum(v == 1))
M[cbind(v, cumsum(v == 1))] <- unlist(df, use.names = FALSE)
M
# [,1] [,2] [,3] [,4]
# [1,] -0.5604756 1.558708 0.07050839 0.1292877
# [2,] -0.2301775 NA NA 1.7150650
# [3,] NA NA NA 0.4609162
M谢谢,但这是可以概括的吗?在我的真实数据集中,变量名是完全不同的,并且没有表示它们是哪些观测值的结尾。它只是在向量v
@spore234中,没有变量名,否则你怎么知道元素应该是哪一列/哪一行呢?我认为你的问题的前提是你有那些一致的变量名。例如,假设您的变量名现在从a
到g
,您怎么知道a
和b
在第1列?您是对的,我在示例中犯了一个错误。第一行总是完整的。因此,每个新的“1”表示新列的开始。是的,正确。它应该是这样的:“如果1出现开始新列,如果不是1填充行x”。@userR啊,是的,我现在明白了。不错的解决方案+1。我还在想着OP想要的东西…谢谢,但这是可以概括的吗?在我的真实数据集中,变量名是完全不同的,并且没有表示它们是哪些观测值的结尾。它只是在向量v
@spore234中,没有变量名,否则你怎么知道元素应该是哪一列/哪一行呢?我认为你的问题的前提是你有那些一致的变量名。例如,假设您的变量名现在从a
到g
,您怎么知道a
和b
在第1列?您是对的,我在示例中犯了一个错误。第一行总是完整的。因此,每个新的“1”表示新列的开始。是的,正确。它应该是这样的:“如果1出现开始新列,如果不是1填充行x”。@userR啊,是的,我现在明白了。不错的解决方案+1。我仍然在思考OP想要什么…这与我的原始答案类似,但OP提到重塑不应基于原始列名,而应仅基于提供的指示向量v
。这与我的原始答案类似,但OP提到,重塑不应基于原始列名,而应仅基于提供的指示符向量v
。这个问题没有什么不清楚的地方。这个问题没有什么不清楚的地方。这是可行的,比“tidyr”方法更快,但似乎有些过分了!这是可行的,并且比“tidyr”方法更快,但似乎有点过头了!