我吮吸循环并且[l,s,v]应用,我需要总结一个大的纵向数据集。我已经彻底搜索了我的问题好几天,我发布这个是因为我无法解决我的问题。
数据看起来像这样:
id var1_dose var1_unit var2_dose var2_unit var3_dose var3_unit
1 2 mL 5 mL 1 mL
2 4 mg 2 mg 4 mg
3 6 mcg 4 mcg 2 mcg
1 1 mL 1 mL 3 mL
2 3 mL 3 mL 5 mL
我希望使用apply或loop并输出var(1-3)剂量作为列表。
我想创建一个新变量,用剂量和单位连接数字,例如在第1行中,var1 = 2mL,var2 = 5mL,var3 = 1mL
非常感谢您的帮助。
答案 0 :(得分:5)
这不是您要求的答案,但我认为这对您和其他人有帮助。请考虑tidying您的数据框。例如:
library(tidyr)
df1 <- data.frame(id = c(1,2,3,1,2),
var1_dose = c(2,4,6,1,3),
var1_unit = c("mL", "mg", "mcg", "mL", "mL"),
var2_dose = c(5,2,4,1,3),
var2_unit = c("mL", "mg", "mcg", "mL", "mL"),
var3_dose = c(1,4,2,3,5),
var3_unit = c("mL", "mg", "mcg", "mL", "mL"),
stringsAsFactors = FALSE)
df1.gather <- gather(df1, variable, value, -id)
df1.tidy <- separate(df1.gather, variable,
into = c("variable", "measurement"), sep = "_")
head(df1.tidy)
# id variable measurement value
# 1 var1 dose 2
# 2 var1 dose 4
# 3 var1 dose 6
# 1 var1 dose 1
# 2 var1 dose 3
# 1 var1 unit mL
# 2 var1 unit mg
# 3 var1 unit mcg
# 1 var1 unit mL
# 2 var1 unit mL
# hacky workaround to get a units column
df1.tidy <- subset(df1.tidy, measurement != "unit")
df1.tidy$unit <- rep(c("mL", "mg", "mcg", "mL", "mL"), 3)
这种结构应该使得汇总,建模和绘图(使用ggplot2)变得更加容易。
答案 1 :(得分:2)
也许,这有助于
Weekly_Lecture CK(I_id, TS_name, WD_name)
答案 2 :(得分:1)
@akrun给出了正确的答案。如果您希望将结果作为列表 -
celery
答案 3 :(得分:0)
为了扩展我对@ neilfws答案的评论(并使用他的示例数据),您的数据最好以更长的形式进行整形,这将使您的分析的其余部分更加容易。但是,您的数据目前处于一种广泛的形式,因此您需要收集(融化)两组列,这比您的平均从长到长的重塑需要更多的工作。
一种选择是收集所有东西然后再扩散到广泛。这很好用,tidyr::spread
非常特别关于索引的一个问题,因此您必须添加第二个ID列来标识结果的行,并且需要仔细考虑该列。
library(tidyverse)
df1_tidy <- df1 %>%
gather(var, val, -id) %>% # gather everything to long form
separate(var, c('var', 'var2')) %>% # separate "var*" from dose/unit
group_by(var2) %>%
mutate(var = parse_number(var), # extract var to integer
id2 = seq(n())) %>% # add ID column for spreading
spread(var2, val, convert = TRUE) %>%
select(-id2) # cleanup
## # A tibble: 15 × 4
## id var dose unit
## * <dbl> <dbl> <int> <chr>
## 1 1 1 2 mL
## 2 1 1 1 mL
## 3 1 2 5 mL
## 4 1 2 1 mL
## 5 1 3 1 mL
## 6 1 3 3 mL
## 7 2 1 4 mg
## 8 2 1 3 mL
## 9 2 2 2 mg
## 10 2 2 3 mL
## 11 2 3 4 mg
## 12 2 3 5 mL
## 13 3 1 6 mcg
## 14 3 2 4 mcg
## 15 3 3 2 mcg
或者,您可以单独设置gather
。这种方法的问题在于它会为您提供您不想要的组合(var1和var3等),因此您必须filter
返回原始文件。
df1_tidy <- df1 %>%
gather(var, dose, contains('dose')) %>%
gather(var_unit, unit, contains('unit')) %>%
mutate_at(vars(contains('var')), parse_number) %>% # extract var numbers
filter(var == var_unit) %>% # filter to matching combinations
select(-var_unit) # cleanup
df1_tidy
## id var dose unit
## 1 1 1 2 mL
## 2 2 1 4 mg
## 3 3 1 6 mcg
## 4 1 1 1 mL
## 5 2 1 3 mL
## 6 1 2 5 mL
## 7 2 2 2 mg
## 8 3 2 4 mcg
## 9 1 2 1 mL
## 10 2 2 3 mL
## 11 1 3 1 mL
## 12 2 3 4 mg
## 13 3 3 2 mcg
## 14 1 3 3 mL
## 15 2 3 5 mL
虽然tidyr没有(yet)具有多聚集功能,需要像上面这样的方法,data.table的melt
版本允许您传递其measure.vars
参数正则表达式模式,启用多聚集。语法看起来很不一样,有不同的东西要清理,但它会带你到同一个地方:
library(data.table)
dt1 <- melt(setDT(df1),
measure.vars = patterns('dose', 'unit'), # set gathering patterns
variable.factor = FALSE, # because factor numbers are evil
value.name = c('dose', 'unit')) # set column names
dt1 <- dt1[, variable := as.integer(variable)][] # cleanup
dt1
## id variable dose unit
## 1: 1 1 2 mL
## 2: 2 1 4 mg
## 3: 3 1 6 mcg
## 4: 1 1 1 mL
## 5: 2 1 3 mL
## 6: 1 2 5 mL
## 7: 2 2 2 mg
## 8: 3 2 4 mcg
## 9: 1 2 1 mL
## 10: 2 2 3 mL
## 11: 1 3 1 mL
## 12: 2 3 4 mg
## 13: 3 3 2 mcg
## 14: 1 3 3 mL
## 15: 2 3 5 mL
无论您选择何种方法,一旦数据整洁,将dose
和unit
结合起来很容易:
# base R
df1_tidy$dose_unit <- paste0(df1_tidy$dose, df1_tidy$unit)
# tidyverse
df1_tidy <- df1_tidy %>% mutate(dose_unit = paste0(dose, unit))
# data.table
dt1 <- dt1[, dose_unit := paste0(dose, unit)][]