在R

时间:2019-05-23 23:02:31

标签: r dplyr

我有一个数据集,其中的一列根据调查概述了某人喝果汁的量。接收者可以回答每天,每周或每月喝多少次果汁。

该列设置为3位整数,其中第一个数字是他们是否每天/每周/每月选择,其余数字是他们在此期间内喝果汁的次数。因此104表示他们每天喝4次果汁。 209意味着每周9次。等

这是结构:

juice <- c(101,204,310)

我想创建一个标准化数据的新列,以便所有这些都是“每周”的数字。因此,如果整数以1(每天)开头,则应将第二个2位数字(例如一个单一数字,例如04 = 4倍)乘以7,并从开头删除“ 1”。如果以2(每周)开头,则只需删除第一位。如果以3(每月)开头,则除以30,再乘以7,然后除去第一位数字。

我是R的新手,也不知道如何解决这个问题-我们将不胜感激!

3 个答案:

答案 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