有条件的代数

时间:2018-06-23 01:55:27

标签: r dplyr

我有这样的数据框

test <- data.frame(gr=rep(letters[1:2],each=6),No=c(100:105,200:205))

   gr  No
1   a 100
2   a 101
3   a 102
4   a 103
5   a 104
6   a 105
7   b 200
8   b 201
9   b 202
10  b 203
11  b 204
12  b 205

No列中,每个gr中的数字都在增加。我需要将gr a与100相加,并将b与50相加,并且需要在此操作后连续减小。

我想创建一个新列,该列随着此增加而连续减少。所以我尝试了

decrese_func <- function(No,gr){

   if(any(gr=="a")){
     No+100

   }
   else
    No+50 
 }

   test%>%
   group_by(gr)%>%
   mutate(new_column=decrese_func(No,gr))

# A tibble: 12 x 3
# Groups:   gr [2]
   gr       No new_column
   <fct> <int>      <dbl>
 1 a       100        200
 2 a       101        201
 3 a       102        202
 4 a       103        203
 5 a       104        204
 6 a       105        205
 7 b       200        250
 8 b       201        251
 9 b       202        252
10 b       203        253
11 b       204        254
12 b       205        255

但是我需要的是这样

 gr       No new_column
   <fct> <int>      <dbl>
 1 a       100        200
 2 a       101        199
 3 a       102        198
 4 a       103        197
 5 a       104        196
 6 a       105        195
 7 b       200        250
 8 b       201        249
 9 b       202        248
10 b       203        247
11 b       204        246
12 b       205        245

我不知道如何连续减少?

谢谢。

2 个答案:

答案 0 :(得分:1)

这不是最优雅的答案,但在此期间,这可能会起作用:

import cv2
import numpy as np

# Create a VideoCapture object
cap = cv2.VideoCapture(0)

# Check if camera opened successfully
if (cap.isOpened() == False): 
  print("Unable to read camera feed")

# Default resolutions of the frame are obtained.The default resolutions are system dependent.
# We convert the resolutions from float to integer.
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))

# Define the codec and create VideoWriter object.The output is stored in 'outpy.avi' file.
out = cv2.VideoWriter('outpy.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))

while(True):
  ret, frame = cap.read()

  if ret == True: 

    # Write the frame into the file 'output.avi'
    out.write(frame)

    # Display the resulting frame    
    cv2.imshow('frame',frame)

    # Press Q on keyboard to stop recording
    if cv2.waitKey(1) & 0xFF == ord('q'):
      break

  # Break the loop
  else:
    break 

# When everything done, release the video capture and video write objects
cap.release()
out.release()

# Closes all the frames
cv2.destroyAllWindows() 
library(dplyr)

test %>% 
  mutate(A = case_when(gr == "a" ~ 100,
                       gr == "b" ~ 50,
                       TRUE ~ NA_real_)) %>% 
  group_by(gr) %>% 
  mutate(B = (1:NROW(gr) - 1) * 2,
         New_Column = No + A - B)

在链的末尾添加# A tibble: 12 x 5 # Groups: gr [2] gr No A B New_Column <fct> <int> <dbl> <dbl> <dbl> 1 a 100 100 0 200 2 a 101 100 2 199 3 a 102 100 4 198 4 a 103 100 6 197 5 a 104 100 8 196 6 a 105 100 10 195 7 b 200 50 0 250 8 b 201 50 2 249 9 b 202 50 4 248 10 b 203 50 6 247 11 b 204 50 8 246 12 b 205 50 10 245 ,仅获得select(gr, No, New_Column)grNo。我留下了其他几列只是为了说明正在发生的事情。

如果要将其包装到函数中,可以执行以下操作:

New_Column
desc_func <- function(group_var, condition, if_true_add, if_false_add, to_number) {
  ifelse(
    group_var == condition, 
    to_number + if_true_add - (1:NROW(group_var) - 1) * 2, 
    to_number + if_false_add - (1:NROW(group_var) - 1) * 2)
}

test %>% 
  group_by(gr) %>% 
  mutate(test_var = desc_func(gr, "a", 100, 50, No))

答案 1 :(得分:1)

这是在base R

中执行此操作的方法
test$New <- with(test, No + c(100, 50)[cumsum(!duplicated(gr))] - 2*(No %% 100))
test$New
#[1] 200 199 198 197 196 195 250 249 248 247 246 245

或与match

略有不同
with(test, No + c(100, 50)[match(gr, unique(gr))] - 2*(No %% 100))