我在R中有一个数据表,其中每一行代表用户在社交媒体平台中的访问。为简单起见,此数据的示例如下:
UserID Channel TW_VisitDuration TW_Activity FB_VisitDuration FB_Activity
aaa TW 30 High
bbb FB 45 Low
每次访问都有一个频道(例如FB / TW),其他列根据此频道填充(仅填充相关列)。 我想要一个新表,其中所有类似的列都缩减为列,并且值来自相关列。在这种情况下,新表将如下所示:
UserID Channel VisitDuration Activity
aaa TW 30 High
bbb FB 45 Low
我编写了一个for循环,逐行进行此评估,但我确信这不是“R方式”(并且循环的性能可能会很差,因为我的数据会缩放)。 这是我写的for循环:
for (i in 1:nrow(res.table)){
cur.channel = res.table[,Channel][i]
for (field in specific.fields){
print(field)
test.t[[field]][i] = res.table[[paste(cur.channel,field,sep='_')]][i]
}
}
如何在不需要逐行的情况下完成这项工作?
答案 0 :(得分:1)
我们可以使用melt
中的data.table
将此转换为' long'格式。此外,该函数可以采用多个patterns
library(data.table)
melt(setDT(df1), measure = patterns("Visit", "Activity"),
value.name = c("VisitDuration", "Activity"), na.rm = TRUE)[, variable := NULL][]
# UserID Channel VisitDuration Activity
#1: aaa TW 30 High
#2: bbb FB 45 Low
df1 <- structure(list(UserID = c("aaa", "bbb"), Channel = c("TW", "FB"
), TW_VisitDuration = c(30L, NA), TW_Activity = c("High", NA),
FB_VisitDuration = c(NA, 45L), FB_Activity = c(NA, "Low")), .Names = c("UserID",
"Channel", "TW_VisitDuration", "TW_Activity", "FB_VisitDuration",
"FB_Activity"), class = "data.frame", row.names = c(NA, -2L))