我有一个数据集,其中包含一个Person ID(个人)列表,每个人使用的某些语言功能以及每个人使用了多少次。看起来像这样:
df <- data.frame(PID = c(1, 1, 2, 2, 2, 3, 3), Feature = c("F2", "F3", "F1", "F2", "F3", "F1", "F3"), Freq = c(2, 1, 3, 1, 2, 4, 3))
ids <- data.frame(PID = 1:3, Level = c("low", "mid", "high"))
我正在将其转换为一个数据行,该数据行每行一个人,语言特征作为列:
f_freq <- data.frame(ids[1:2], matrix(nrow = nrow(ids), ncol = 3))
f_names <- c("F1", "F2", "F3)
names(f_freq)[3:5] <- f_names
所以我想将频率信息从第一个数据帧(df)映射到新的(f_freq),并为每个个人未使用的功能插入0。我写了一个for循环来达到这个目的:
for (h in 1:length(f_names)) {
for (j in 1:nrow(f_freq)) {
t1 <- filter(df, Feature == f_names[[h]])
if (f_freq$PID[j] %in% t1$PID) {
f_freq[j, f_names[[h]]] <- t1[t1$PID == f_freq$ID[j], "Freq"]
} else {
out[j, f_names[[h]]] <- 0
}
}
}
但是它只返回NA。当我输入每个功能名称时,它会起作用,如下所示。
for (h in 1:length(f_names)) {
for (j in 1:nrow(f_freq)) {
t1 <- filter(df, Feature == "F1")
if (f_freq$PID[j] %in% t1$PID) {
f_freq[j, "F1"] <- t1[t1$PID == f_freq$ID[j], "Freq"]
} else {
out[j, "F1"] <- 0
}
}
}
但是我在实际数据中有35个功能,因此我想使它自动化。我不确定为什么第一个循环不起作用。如果有人知道如何解决此问题,请告诉我!!
答案 0 :(得分:2)
我们可以做到没有任何循环。只需对第一个数据集“ df”和“ f_freq”中的列子集进行left_join
(无需在新数据集中创建“ F \ d +”列)。使用spread
从“长”变形为“宽”
library(tidyverse)
left_join(df, f_freq[1:2]) %>%
spread(Feature, Freq, fill = 0)
# PID Level F1 F2 F3
#1 1 low 0 2 1
#2 2 mid 3 1 2
#3 3 high 4 0 3
如果我们仅需要为'F'列提供二进制输出,请将'Freq'更改为1并执行spread
left_join(df, f_freq[1:2]) %>%
mutate(Freq = 1) %>%
spread(Feature, Freq, fill = 0)