使用行中的用户条目重塑R数据,为每个用户折叠
请原谅我对R世界的新认识,谢谢你的帮助 我想分析一个实验的数据 数据是长格式的,需要重新调整为宽格式,但我不知道具体怎么做。熔化/浇铸和重塑的大多数示例都处理更简单的数据帧 每次受试者回答一个实验问题时,他的用户名、位置、年龄和性别都记录在一行中,然后他在一系列问题上的实验数据被输入到这些变量旁边。问题是,他们可以回答实验中的任何问题,也可以回答不同的项目(这很复杂,但必须是这样) 原始数据如下所示:使用行中的用户条目重塑R数据,为每个用户折叠,r,reshape,R,Reshape,请原谅我对R世界的新认识,谢谢你的帮助 我想分析一个实验的数据 数据是长格式的,需要重新调整为宽格式,但我不知道具体怎么做。熔化/浇铸和重塑的大多数示例都处理更简单的数据帧 每次受试者回答一个实验问题时,他的用户名、位置、年龄和性别都记录在一行中,然后他在一系列问题上的实验数据被输入到这些变量旁边。问题是,他们可以回答实验中的任何问题,也可以回答不同的项目(这很复杂,但必须是这样) 原始数据如下所示: User_id, location, age, gender, Item, Resp 1, C
User_id, location, age, gender, Item, Resp
1, CA, 22, M, A, 1
1, CA, 22, M, B, -1
1, CA, 22, M, C, -1
1, CA, 22, M, D, 1
1, CA, 22, M, E,-1
2, MD, 27, F, A, -1
2, MD, 27, F, B, 1
2, MD, 27, F, C, 1
2, MD, 27, F, E, 1
2, MD, 27, F, G, -1
2, MD, 27, F, H, -1
User_id, location, age, gender, A, B, C, D, E, F, G, H
1, CA, 22, M, 1, -1, -1, 1, -1, 0, 0, 0,
2, MD, 27, F, -1, 1, 1, 1, 0, 1, -1, -1
我希望重新调整此数据,使每个用户都位于一行上,如下所示:
User_id, location, age, gender, Item, Resp
1, CA, 22, M, A, 1
1, CA, 22, M, B, -1
1, CA, 22, M, C, -1
1, CA, 22, M, D, 1
1, CA, 22, M, E,-1
2, MD, 27, F, A, -1
2, MD, 27, F, B, 1
2, MD, 27, F, C, 1
2, MD, 27, F, E, 1
2, MD, 27, F, G, -1
2, MD, 27, F, H, -1
User_id, location, age, gender, A, B, C, D, E, F, G, H
1, CA, 22, M, 1, -1, -1, 1, -1, 0, 0, 0,
2, MD, 27, F, -1, 1, 1, 1, 0, 1, -1, -1
我认为这只是找到正确的重塑方程的问题,但我已经做了几个小时了,我不能完全得到我想要的,因为大多数例子没有重复的人口统计数据,因此可以更简单地进行轮换。非常抱歉,如果我忽略了一些简单的内容。有一个名为的包,它使数据帧的融合和重塑变得更加容易。在您的情况下,您可以直接使用
tidyr::spread
:
result = spread(df, Item, Resp)
但是,这将用NA
填充缺少的条目:
User_id location age gender A B C D E G H
1 1 CA 22 M 1 -1 -1 1 -1 NA NA
2 2 MD 27 F -1 1 1 NA 1 -1 -1
您可以通过替换它们来解决此问题:
result[is.na(result)] = 0
result
# User_id location age gender A B C D E G H
# 1 1 CA 22 M 1 -1 -1 1 -1 0 0
# 2 2 MD 27 F -1 1 1 0 1 -1 -1
…或使用fill
参数:
result = spread(df, Item, Resp, fill = 0)
为完整起见,另一种方法(即复制原始的数据帧
)通过聚集
(通常称为“融化”):
-这里的最后一个参数告诉
gather
要收集哪些列(并且它支持简明的范围语法)。使用data.table
可以执行以下操作:
library(data.table)
> dcast(dt, User_id + location + age ~ Item, value.var = "Resp", fill = 0L)
User_id location age A B C D E G H
1: 1 CA 22 1 -1 -1 1 -1 0 0
2: 2 MD 27 -1 1 1 0 1 -1 -1
以下是始终优雅的
stats::重塑版
(newdf <- reshape(df, direction = "wide", timevar = "Item", idvar = names(df)[1:4]))
# User_id location age gender Resp. A Resp. B Resp. C Resp. D Resp. E Resp. G Resp. H
# 1 1 CA 22 M 1 -1 -1 1 -1 NA NA
# 6 2 MD 27 F -1 1 1 NA 1 -1 -1
当然,如果我们把代码分成两行,代码肯定会更清晰。另外,请注意,原始数据中的Item
中没有F
,因此输出与原始数据之间存在差异
数据:
df <- structure(list(User_id = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L,
2L, 2L), location = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L,
2L, 2L, 2L), .Label = c(" CA", " MD"), class = "factor"), age = c(22L,
22L, 22L, 22L, 22L, 27L, 27L, 27L, 27L, 27L, 27L), gender = structure(c(2L,
2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c(" F", " M"
), class = "factor"), Item = structure(c(1L, 2L, 3L, 4L, 5L,
1L, 2L, 3L, 5L, 6L, 7L), .Label = c(" A", " B", " C", " D", " E",
" G", " H"), class = "factor"), Resp = c(1, -1, -1, 1, -1, -1,
1, 1, 1, -1, -1)), .Names = c("User_id", "location", "age", "gender",
"Item", "Resp"), class = "data.frame", row.names = c(NA, -11L
))
df Nice,tidyr::spread
具有相同的参数。一致性很好。reformae2::dcast
也有fill
参数,所以不确定您的意思是什么!我读了这篇文章,然后跳过了它。你的解决方案很有效。对于任何其他发现此项的人:spread也会找到您的重复条目;我用df@MichaelChirico删除了它为什么?因为您使用了fill=0
?@DavidArenburg-Hmm。。这是一个正确的观点。让我也在我的重复文章中寻找一些不在链接文章中的东西:-)