根据条件使用其他向量中的值更改列中的值

时间:2019-06-12 20:20:51

标签: r dataframe dplyr data-manipulation

想象一下我有这个df。

library(dplyr)
library(scales)
df <- data.frame("item" = 1:10, "quantity" = c(21,15,12,14,26,12,13,15,24,26), "value" = c(90,110,105,102,86,112,75,84,34,99))

理想情况下,我想将值最大化为100。因此,我想获取值大于95的任何项目,然后将其缩放为1:5的范围。然后,我想将缩放后的值添加到95之上,以获得介于95和100之间的值。这是我目前拥有的:

x <- df[df$value >= 95,]
x <- x$value
x <- rescale(x, to = c(0,5))
x  # [1] 4.23, 2.31, 1.15, 5.00, 0.00
df <- df %>% mutate(value = ifelse(value >= 95, 95 + x, value))

这给了我95+x[1]的所有大于95的值,您可以想象。我认为我需要一个for循环,但无法完全弄清楚如何构造它。谢谢。

所需的输出将是:

Item Quantity Value
1       21    90 
2       15    99.23
3       12    97.31
4       14    96.15
5       26    86 
6       12    100
7       13    75 
8       15    84
9       24    34 
10      26    95

5 个答案:

答案 0 :(得分:2)

我不确定这是否是您要寻找的东西,但是使用dplyr和scales软件包:

df %>% 
 mutate(Value = ifelse(Value >= 95, 95 + scales::rescale(Value, to = c(1, 5)), Value))

编辑:

df %>% 
  filter(Value >= 95) %>% 
  mutate(Value = 95 + scales::rescale(Value, to = c(0, 5))) %>% 
  bind_rows(filter(df, Value < 95)) %>% 
  arrange(Item)

答案 1 :(得分:2)

可以通过 base r 中的一个简单子集来实现:

df <- data.frame("item" = 1:10, 
                 "quantity" = c(21,15,12,14,26,12,13,15,24,26),
                 "value" = c(90,110,105,102,86,112,75,84,34,99))

df[df$value >= 95,"value"] <- 95 + scales::rescale(df[df$value >= 95,"value"], to=c(0, 5))

df
#>    item quantity     value
#> 1     1       21  90.00000
#> 2     2       15  99.23077
#> 3     3       12  97.30769
#> 4     4       14  96.15385
#> 5     5       26  86.00000
#> 6     6       12 100.00000
#> 7     7       13  75.00000
#> 8     8       15  84.00000
#> 9     9       24  34.00000
#> 10   10       26  95.00000

reprex package(v0.3.0)于2019-06-12创建

答案 2 :(得分:1)

不确定我已经掌握了预期的输出,但可能类似于以下内容:

library(dplyr)

df %>%
  group_by(grp = Value >= 95) %>%
  mutate(New_Value = ifelse(Value >= 95, 95 + ntile(Value, 5), Value))

# A tibble: 10 x 5
# Groups:   grp [2]
    Item Quantity Value grp   New_Value
   <int>    <dbl> <dbl> <lgl>     <dbl>
 1     1       21    90 FALSE        90
 2     2       15   110 TRUE         99
 3     3       12   105 TRUE         98
 4     4       14   102 TRUE         97
 5     5       26    86 FALSE        86
 6     6       12   112 TRUE        100
 7     7       13    75 FALSE        75
 8     8       15    84 FALSE        84
 9     9       24    34 FALSE        34
10    10       26    99 TRUE         96

使用相同的方法,但使用scales::rescale()

df %>%
  group_by(grp = Value >= 95) %>%
  mutate(New_Value = ifelse(Value >= 95, 95 + scales::rescale(Value, c(0,5)), Value))

# A tibble: 10 x 5
# Groups:   grp [2]
    Item Quantity Value grp   New_Value
   <int>    <dbl> <dbl> <lgl>     <dbl>
 1     1       21    90 FALSE      90  
 2     2       15   110 TRUE       99.2
 3     3       12   105 TRUE       97.3
 4     4       14   102 TRUE       96.2
 5     5       26    86 FALSE      86  
 6     6       12   112 TRUE      100  
 7     7       13    75 FALSE      75  
 8     8       15    84 FALSE      84  
 9     9       24    34 FALSE      34  
10    10       26    99 TRUE       95  

答案 3 :(得分:1)

这在data.table中,但是这就是我要做的方式

library(data.table)
dt <- data.table("Item" = 1:10,
                 "Quantity" = c(21,15,12,14,26,12,13,15,24,26),
                 "Value" = c(90,110,105,102,86,112,75,84,34,99))

dt[Value >= 95, Value := 95 + (Value - 95) / (max(Value) - 95) * 5]

也是在基地

df <- data.frame("Item" = 1:10,
                 "Quantity" = c(21,15,12,14,26,12,13,15,24,26),
                 "Value" = c(90,110,105,102,86,112,75,84,34,99))

x <- df[df$Value >= 95, "Value"] - 95
df[df$Value >= 95, "Value"] <- 95 + x / max(x) * 5

答案 4 :(得分:0)

这也起作用:

x <- df[df$value >= 95,]
x <- x$value
x <- rescale(x, to = c(0,5))
x  # [1] 4.23, 2.31, 1.15, 5.00, 0.00
df$Value[df$Value>95] <- 95 + x