R函数踩坑
variaty of R function
1 分析场景与R包
1.1 统计制表 vs janitor::tabyl
tabyls: a tidy, fully-featured approach to counting things. see link
优点:
方便统计频次和频率
方便添加行合计
方便调整数据格式(百分数等)
可以结合
knitr::kable()
输出
不足:
janitor::tabyl()
仅适合处理原始数据,并且是data.frame
或vector
。
1.1.1 注意函数使用次序
特别需要注意系列janitor::adorn_xx()
函数的使用先后顺序关系。概括起来需要小心的是:
先计算汇总,再设置格式。其核心要点在于,数据列格式的变换,会导致数据列类型(type)的改变,比如
numeric
类型会变为character
类型。例如,需要先adorn_total("rows")
进行行汇总,再adorn_pct_formatting()
把比率转换为百分数。没有被汇总的
adorn_total()
,也不会被进一步调整格式adorn_pct_formatting()
。这意味着手动计算的占比列(小数如0.32),不能够使用adorn_pct_formatting()
调整为百分数(如32%)。添加汇总计算
adorn_total()
,结果将不再保持为标准数据表(tidy data table)。因此需要额外处理不适合汇总的列或行。例如累积百分比和累积次数,就不应该有汇总(Total)值。
1.1.2 指定列进行汇总或调整格式
首先,指定列进行汇总或调整格式需要满足前述函数使用的先后次序关系。
其次,指定列进行汇总或调整格式需要完整使用
janitor::adorn_xx()
函数的所有参数设置。这一点非常不人性。最后,指定列进行汇总或调整格式需要使用
dplyr
包的select
语法,如all_of(contains(“p”))`。
require(DT)
require(janitor)
char <-c("非常不满意","不满意","一般","满意","非常满意")
reps <- c(24L, 108L,93L, 45L,30L)
sat_list <- rep(char, reps)
sat <- data.frame(groups=LETTERS[1:5],
satisfication = sat_list,
row.names=NULL) %>%
mutate(satisfication = factor(satisfication, levels = char))
cum_calc <- sat %>%
janitor::tabyl(satisfication) %>%
mutate(min_cum_n = cumsum(n),
min_cum_p = cumsum(percent), #<<
max_cum_n =rev( cumsum(rev(n))), #<<
max_cum_p =rev( cumsum(rev(percent))))
cum_format<- cum_calc %>%
mutate(min_cum_p = scales::percent(min_cum_p,accuracy = 0.1), #<<
max_cum_p = scales::percent(max_cum_p,accuracy = 0.1)) %>%
janitor::adorn_totals(.,where = "row",fill = "-",na.rm = TRUE, #<<
name = "Total", all_of(c("n","percent"))) %>%
janitor::adorn_pct_formatting(.,digits = 1, #<<
rounding ="half to even",
affix_sign = TRUE,
all_of(c("percent"))) #<<
2 分析场景与R函数
2.1 数据类型读取
- 读取spss文件。为了避免出现编码错误(中文等多字节问题),建议使用
foreign::read.spss()
函数,而不宜使用haven::read_sav()
函数
df_computer<- haven::read_sav("../data/case-3.6-computer-sales.sav",encoding = "UTF-8", .name_repair = "unique")
knitr::kable(df_computer)
df_computer<- foreign::read.spss("../data/case-3.6-computer-sales.sav", to.data.frame=TRUE)
knitr::kable(df_computer)
2.2 生成重复数据rep()
分析场景:生成指定的重复数据,要求指定被重复的vector("char vec")
,以及指定各自重复的次数vector("times vec")
。
- 踩坑函数1:直接
rep()
。
require(magrittr)
brand<- c("果汁","矿泉水","绿茶","其他","碳酸饮料")
reps <- c(6L, 10L,11L, 8L,15L)
rep(brand, reps)
[1] "果汁" "果汁" "果汁" "果汁" "果汁" "果汁"
[7] "矿泉水" "矿泉水" "矿泉水" "矿泉水" "矿泉水" "矿泉水"
[13] "矿泉水" "矿泉水" "矿泉水" "矿泉水" "绿茶" "绿茶"
[19] "绿茶" "绿茶" "绿茶" "绿茶" "绿茶" "绿茶"
[25] "绿茶" "绿茶" "绿茶" "其他" "其他" "其他"
[31] "其他" "其他" "其他" "其他" "其他" "碳酸饮料"
[37] "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料"
[43] "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料"
[49] "碳酸饮料" "碳酸饮料"
- 踩坑函数2:
mapply()
+rep()
。这个要复杂一点。
drink <- mapply(FUN = rep, x=brand, times = reps) %>%
unlist()
names(drink) <-NULL
drink
[1] "果汁" "果汁" "果汁" "果汁" "果汁" "果汁"
[7] "矿泉水" "矿泉水" "矿泉水" "矿泉水" "矿泉水" "矿泉水"
[13] "矿泉水" "矿泉水" "矿泉水" "矿泉水" "绿茶" "绿茶"
[19] "绿茶" "绿茶" "绿茶" "绿茶" "绿茶" "绿茶"
[25] "绿茶" "绿茶" "绿茶" "其他" "其他" "其他"
[31] "其他" "其他" "其他" "其他" "其他" "碳酸饮料"
[37] "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料"
[43] "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料" "碳酸饮料"
[49] "碳酸饮料" "碳酸饮料"
2.3 探查样本数据集是否缺失
- 问题:
lm(formula = lm.mod, data = lm.dt)
回归提示warning。表明数据集lm.dt
中存在缺失值。
12 observation deleted due to missingness
处理:采用函数
stats::complete.cases(lm.dt)
来使用无缺失的数据集。或者查看存在缺失数据的行which(!stats::complete.cases(lm.dt))
。