我有一个类似于以下示例的数据框:
> df <- data.frame(imp = c("Johny", "Johny", "Lisa", "Max"), item = c(5025, 1101, 2057, 1619))
> df
imp item
[1,] "Johny" "5025"
[2,] "Johny" "1101"
[3,] "Lisa" "2057"
[4,] "Max" "1619"
我希望每个user
都有一个唯一的行。最终结果应该是这样的:
> df
imp item1 item2
[1,] "Johny" "5025" "1101"
[2,] "Lisa" "2057" NA
[3,] "Max" "1619" NA
答案 0 :(得分:3)
## Add an ID column to distinguish multiple measurements per imp
## There's probably a better way to do this?
df <- do.call(rbind, lapply(
split(df, df$imp),
function(x) {
x$item_id <- seq(nrow(x))
return(x)
}
))
## Then simply use the dcast function from the reshape2 package
df <- dcast(df, imp ~ item_id, value.var='item')
## Tidy up the column names
names(df) <- sub('^(\\d+)$', 'item_\\1', names(df))
答案 1 :(得分:3)
使用data.table v 1.9.6+我们可以将表达式直接传递给公式。有关详情,请参阅?dcast
以及示例部分。
require(data.table) # v1.9.6+
dcast(setDT(df), imp ~ paste0("item",
df[, seq_len(.N), by=imp]$V1), value.var="item")
# imp item1 item2
# 1: Johny 5025 1101
# 2: Lisa 2057 NA
# 3: Max 1619 NA
修改强>
使用data.table v1.9.8 +你可以简单地做
require(data.table) # v1.9.8+
dcast(setDT(df), imp ~ rowid(imp, prefix = "item"), value.var = "item")
答案 2 :(得分:1)
使用data.table
的方法怎么样:
require(data.table)
dt <- data.table(imp = c("Johny", "Johny", "Lisa", "Max"),
item = c(5025, 1101, 2057, 1619))
dt[, list(items = list(unique(item))), by=imp]
# to keep all items, not only uniques
dt[, list(items = list(item)), by=imp]
这为您提供了一个&#34;项目列表&#34;每个&#34; imp&#34; ...
答案 3 :(得分:1)
通过ave
(以创建您的&#34;时间&#34;变量)和reshape
(来自&#34; long& #34;到&#34;宽&#34;):
df$times <- ave(rep(1, nrow(df)), df$imp, FUN = seq_along)
df
# imp item times
# 1 Johny 5025 1
# 2 Johny 1101 2
# 3 Lisa 2057 1
# 4 Max 1619 1
reshape(df, direction = "wide", idvar="imp", timevar="times")
# imp item.1 item.2
# 1 Johny 5025 1101
# 3 Lisa 2057 NA
# 4 Max 1619 NA