我有一个数据集,其中的一列根据调查概述了某人喝果汁的量。接收者可以回答每天,每周或每月喝多少次果汁。
该列设置为3位整数,其中第一个数字是他们是否每天/每周/每月选择,其余数字是他们在此期间内喝果汁的次数。因此104表示他们每天喝4次果汁。 209意味着每周9次。等
这是结构:
juice <- c(101,204,310)
我想创建一个标准化数据的新列,以便所有这些都是“每周”的数字。因此,如果整数以1(每天)开头,则应将第二个2位数字(例如一个单一数字,例如04 = 4倍)乘以7,并从开头删除“ 1”。如果以2(每周)开头,则只需删除第一位。如果以3(每月)开头,则除以30,再乘以7,然后除去第一位数字。
我是R的新手,也不知道如何解决这个问题-我们将不胜感激!
答案 0 :(得分:2)
使用一些矢量化索引进行操作。我已经刻痕了@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
答案 1 :(得分:1)
> 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)))
答案 2 :(得分:0)
我们可以在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