我有两个数据框 - 第一个是简单的数字观察/某些变量的值:
var1 <- c(1,0,0,1)
var2 <- c(1,1,2,0)
var3 <- c(1,2,0,1)
var4 <- c(2,1,0,1)
var5 <- c(1,2,0,1)
var6 <- c(1,1,1,1)
df <- data.frame(var1, var2, var3, var4, var5, var6)
第二个数据框给出了变量的类别:
var_names <- c("var1", "var2", "var3", "var4", "var5", "var6")
sub_type <- c("red", "blue", "red", "green", "green", "blue")
var_types <- data.frame(var_names, sub_type)
我希望能够为每个类别添加值并将其放入新数据框中。因此,从这个例子中,我有一个4行/观察的新数据帧,用于红色,蓝色和蓝色的3个变量。绿色。看似简单,但我被卡住了。
答案 0 :(得分:2)
使用tidyr
和dplyr
。 jazzurro修改了答案:
library(tidyr)
library(dplyr)
df %>%
mutate(id = row_number()) %>%
gather(key = "var_names", value = "value", -id) %>%
left_join(var_types) %>%
group_by(sub_type, id) %>%
summarize(total = sum(value)) %>%
spread(sub_type, total)
返回:
# A tibble: 4 x 4
id blue green red
<int> <dbl> <dbl> <dbl>
1 1 2.00 3.00 2.00
2 2 2.00 3.00 2.00
3 3 3.00 0 0
4 4 1.00 2.00 2.00
我使用的数据。请注意,我更改了var_types
df
以将字符串视为character
而不是factor
:
df <- data.frame(
var1 = c(1,0,0,1),
var2 = c(1,1,2,0),
var3 = c(1,2,0,1),
var4 = c(2,1,0,1),
var5 = c(1,2,0,1),
var6 = c(1,1,1,1)
)
var_types <- data.frame(
var_names = c("var1", "var2", "var3", "var4", "var5", "var6"),
sub_type = c("red", "blue", "red", "green", "green", "blue"),
stringsAsFactors = FALSE
)
答案 1 :(得分:2)
阅读您的问题,您似乎想要执行以下操作。你说“红色,蓝色和绿色的3个变量的4行/观察的新数据帧”。所以我认为你想拥有一个包含四行三列(三种颜色)的数据框。首先,我将行号添加到df
并以长格式转换数据。在color
列中,我有var1
,var2
和var3
等变量名称。我想把它们改成颜色。我已使用mutate()
在match()
中完成了此操作。然后,按行号和颜色对数据进行分组,我总结了值。最后,我将数据帧转换为宽格式。如有必要,您要删除输出中的rowname
。
library(tidyverse)
rownames_to_column(df) %>%
gather(key = color, value = value, -rowname) %>%
mutate(color = var_types$sub_type[match(color, var_types$var_names)]) %>%
group_by(rowname, color) %>%
summarize(total = sum(value)) %>%
spread(key = color, value = total)
rowname blue green red
<chr> <dbl> <dbl> <dbl>
1 1 2.00 3.00 2.00
2 2 2.00 3.00 2.00
3 3 3.00 0 0
4 4 1.00 2.00 2.00
修改强>
或者,您也可以执行以下操作。您为每种颜色选择列并使用rowSums()
。然后,您创建一个数据框并为其指定列名称。
colors <- unique(var_types$sub_type)
colors %>%
map(function(x) rowSums(df[, which(var_types$sub_type == x)])) %>%
as.data.frame %>%
setNames(colors)
red blue green
1 2 2 3
2 2 2 3
3 0 3 0
4 2 1 2