首页 > 解决方案 > R:从数据中创建指标变量并提取类别

问题描述

我有一个数据框df,用于存储不同年份几千株植物的平均高度(以厘米为单位):

Name    Year    Height
Plant1  2010    440
Plant2  2011    60
Plant1  2011    1980
Plant3  2013    650
Plant4  2016    210

我想做以下事情:

a) 为 400 厘米和 2000 厘米(含)之间的每个 50 厘米高度间隔创建一个变量,其中两个变量 <400 和 >2000。df应该是这样的:

Name    Year    Height h_0_400 h_400 h_450 h_500 h_550 etc.
Plant1  2010    440    
Plant2  2011    60
Plant1  2011    1980
Plant3  2013    640
Plant4  2016    210

b) 根据实际情况分配变量 0 或 1 height

Name    Year    Height h_0_400 h_400 h_450 h_500 h_550 etc.
Plant1  2010    440    0       1     0     0     0
Plant2  2011    60     1       0     0     0     0
Plant1  2011    1980   0       0     0     0     0
Plant3  2013    640    0       0     0     0     0
Plant4  2016    210    1       0     0     0     0

c) 添加一个变量,指示heights条目属于哪个类别

Name    Year    Height h_0_400 h_400 h_450 h_500 h_550 etc. height_index
Plant1  2010    440    0       1     0     0     0          h_400
Plant2  2011    60     1       0     0     0     0          h_0_400
Plant1  2011    1980   0       0     0     0     0          h_1950
Plant3  2013    640    0       0     0     0     0          h_600
Plant4  2016    210    1       0     0     0     0          h_0_400

我不知道如何解决这个问题,并希望有任何见解。到目前为止,我已经尝试使用seq(400,2000,by=1)并删除不需要的值,但这似乎非常低效。我很高兴与任何软件包一起工作。非常感谢!

标签: rcategorical-datadummy-variableindicator

解决方案


一个选项是使用cut(或使用findInterval)创建一个变量组,然后重塑为宽格式

library(dplyr)
library(tidyr)
library(stringr)
out <- df %>%
   # // create grouping variable with cut based on the Height
   mutate(ind = cut(Height, breaks = c(-Inf, c(0, seq(400, 2000,
          by = 50 ))), labels = c('h_0_400', 
  str_c('h_', seq(400, 2000, by = 50)))), height_index = ind, n = 1)  %>%
   # // reshape to wide format
   pivot_wider(names_from = ind, values_from = n, values_fill= list(n = 0))

# // missing columns are created with setdiff and assigned to 0
out[setdiff(levels(out$height_index), out$height_index)] <- 0

数据

df <- structure(list(Name = c("Plant1", "Plant2", "Plant1", "Plant3", 
"Plant4"), Year = c(2010L, 2011L, 2011L, 2013L, 2016L), Height = c(340L, 
60L, 1980L, 650L, 210L)), class = "data.frame", row.names = c(NA, 
-5L))

推荐阅读