我有一个数据集,其中有一列概述了人们喝果汁的量,这是基于一项调查。接受者可以回答每天、每周或每月喝果汁的次数。
该列被设置为一个3位数的整数,其中第一个数字是他们是否选择了每天/每周/每月,其余的数字是他们在这段时间内喝果汁的次数。所以104人意味着他们每天喝4次果汁。209次意味着每周9次。等。
结构是这样的:
juice <- c(101,204,310)
我想创建一个新的列来标准化数据,这样所有的数据都是“每周”数字。因此,如果整数以1 (daily)开头,它应该将第二个2位数(作为单个数字,例如04 =4倍)乘以7,并从开头删除"1“。如果它以2(每周)开头,只需删除第一个数字。如果以3(每月)开头,则除以30,再乘以7,然后去掉第一个数字。
我是R的新手,不知道如何处理这个问题--任何帮助都将不胜感激!
发布于 2019-05-24 08:33:34
使用一些向量化的索引来实现。我从@divibisan中截取了示例数据:
df <- data.frame(juice = c(104, 106, 204, 209, 302, 332, 111))
c(7,1,7/30)[df$juice %/% 100] * df$juice %% 100
#[1] 28.0000000 42.0000000 4.0000000 9.0000000 0.4666667 7.4666667 77.0000000
发布于 2019-05-24 07:26:39
> dat_3digits <- data.frame(drinks = c(104, 209 , 301))
>
> library(tidyverse)
> dat_3digits %>%
mutate(freq = sub("\\d{2}$", "", drinks)%>% as.numeric,
times = sub("\\d{1}", "", drinks) %>% as.numeric,
new_drinks = if_else(freq == 1, times * 7,
if_else(freq == 3, (times/30)*7, freq)))
drinks freq times new_drinks
1 104 1 4 28.0000000
2 209 2 9 2.0000000
3 301 3 1 0.2333333
使用R base和substr
代替sub
transform(transform(dat_3digits,
freq = as.numeric(substr(drinks, start=1, stop=1)),
drinks2 = as.numeric(substr(drinks, start=2, stop=3))),
new_drinks = ifelse(freq == 1, drinks2 * 7,
if_else(freq == 3, (drinks2/30)*7, freq)))
发布于 2019-05-24 07:29:26
我们可以在tidyverse中使用separate
拆分饮料数据,然后使用case_when
将计数乘以适当的数量:
library(tidyverse)
df <- data.frame('juice' = c(104, 106, 204, 209, 302, 332, 111))
df %>%
separate(juice, into = c('period', 'drinks'), sep = 1) %>% # split after 1st character
mutate(
drinks = as.numeric(drinks), # convert number of drinks to numeric
dpw = case_when( # then multiply based on the value of the first period
period == 1 ~ drinks * 7,
period == 2 ~ drinks,
period == 3 ~ (drinks / 30) * 7 ))
period drinks dpw
1 1 4 28.0000000
2 1 6 42.0000000
3 2 4 4.0000000
4 2 9 9.0000000
5 3 2 0.4666667
6 3 32 7.4666667
7 1 11 77.0000000
https://stackoverflow.com/questions/56283921
复制相似问题