带有for循环的函数创建一个值为1:n的列,该列由另一列

时间:2017-10-18 05:33:49

标签: r function for-loop if-statement

我有一个类似以下的数据框

my_df=data.frame(x=runif(100, min = 0,max = 60),
           y=runif(100, min = 0,max = 60)) #x and y in cm

有了这个,我需要一个新的列,其值为1到36,每10厘米匹配xy。例如,如果0<=x<=10 & 0<=y<=10,则输入1,然后输入10<=x<=20 & 0<=y<=10,将2等等放到最多6,然后{7}从7开始到12,等等。我试图制作一个函数0<=x<=10 & 10<=y<=20重复if的间隔6次,每次迭代x的间隔增加10。这是函数

y

我得到了

#my miscarried function 'zones'

>zones= function(x,y) {
     i=vector(length = 6)
     n=vector(length = 6)
     z=vector(length = 36)  
     i[1]=0
     z[1]=0
     n[1]=1

for (t in 1:6) {

  if (0<=x & x<10 & i[t]<=y & y<i[t]+10) { z[t] = n[t]} else

        if (10<=x & x<20 & i[t]<=y & y<i[t]+10) {z[t]=n[t]+1} else 
               if (20<=x & x<30 & i[t]<=y & y<i[t]+10) {z[t]=n[t]+2} else 
                       if (30<=x & x<40 & i[t]<=y & y<i[t]+10) {z[t]=n[t]+3} else
                             if (40<=x & x<50 & i[t]<=y & y<i[t]+10) {z[t]=n[t]+4}else
                                    if (50<=x & x<=60 & i[t]<=y & y<i[t]+10) {z[t]=n[t]+5} 
else {i[t+1]=i[t]+10
      n[t+1]=n[t]+6}
                       }

return(z)

}


>xy$z=zones(x=xy$x,y=xy$y)

请在我独自死之前帮助我!

3 个答案:

答案 0 :(得分:2)

我认为这可以解决问题。

a <- cut(my_df$x, (0:6) * 10)
b <- cut(my_df$y, (0:6) * 10)
z <- interaction(a, b)

levels(z)
 [1] "(0,10].(0,10]"   "(10,20].(0,10]"  "(20,30].(0,10]"  "(30,40].(0,10]" 
 [5] "(40,50].(0,10]"  "(50,60].(0,10]"  "(0,10].(10,20]"  "(10,20].(10,20]"
 [9] "(20,30].(10,20]" "(30,40].(10,20]" "(40,50].(10,20]" "(50,60].(10,20]"
[13] "(0,10].(20,30]"  "(10,20].(20,30]" "(20,30].(20,30]" "(30,40].(20,30]"
[17] "(40,50].(20,30]" "(50,60].(20,30]" "(0,10].(30,40]"  "(10,20].(30,40]"
[21] "(20,30].(30,40]" "(30,40].(30,40]" "(40,50].(30,40]" "(50,60].(30,40]"
[25] "(0,10].(40,50]"  "(10,20].(40,50]" "(20,30].(40,50]" "(30,40].(40,50]"
[29] "(40,50].(40,50]" "(50,60].(40,50]" "(0,10].(50,60]"  "(10,20].(50,60]"
[33] "(20,30].(50,60]" "(30,40].(50,60]" "(40,50].(50,60]" "(50,60].(50,60]"

如果这种类型的水平不适合您的口味,请按以下方式更改:

levels(z) <- 1:36

答案 1 :(得分:1)

这就是你要追求的吗?结果数字位于res列中:

# Get bin index for x values and y values
my_df$bin1 <- as.numeric(cut(my_df$x, breaks = seq(0, max(my_df$x) + 10, by = 10)));
my_df$bin2 <- as.numeric(cut(my_df$y, breaks = seq(0, max(my_df$x) + 10, by = 10)));

# Multiply bin indices
my_df$res <- my_df$bin1 * my_df$bin2;

> head(my_df)
          x         y bin1 bin2 res
1 49.887499 47.302849    5    5  25
2 43.169773 50.931357    5    6  30
3 10.626466 43.673533    2    5  10
4 43.401454  3.397009    5    1   5
5  7.080386 22.870539    1    3   3
6 39.094724 24.672907    4    3  12

为了说明目的,我已经分解了这些步骤;您可能不希望保留中间列bin1bin2

答案 2 :(得分:1)

我们可能需要一个表格来显示x,y和z之间的关系。之后,我们可以定义一个函数来进行连接。

该解决方案与此帖(R dplyr join by range or virtual column)相关并受到启发。您可能还会发现其他解决方案很有用。

# Set seed for reproducibility
set.seed(1)

# Create example data frame
my_df <- data.frame(x=runif(100, min = 0,max = 60),
                    y=runif(100, min = 0,max = 60))

# Load the dplyr package
library(dplyr)

# Create a table to show the relationship between x, y, and z 
r <- expand.grid(x_from = seq(0, 50, 10), y_from = seq(0, 50, 10)) %>%
  mutate(x_to = x_from + 10, y_to = y_from + 10, z = 1:n())

# Define a function for dynamic join
dynamic_join <- function(d, r){

  if (!("z" %in% colnames(d))){
    d[["z"]] <- NA_integer_
  }

  d <- d %>%
    mutate(z = ifelse(x >= r$x_from & x < r$x_to & y >= r$y_from & y < r$y_to, 
                      r$z, z))
  return(d)
}

re_dynamic_join <- function(d, r){
  r_list <- split(r, r$z)
  for (i in 1:length(r_list)){
    d <- dynamic_join(d, r_list[[i]])
  }
  return(d)
}

# Apply the function
re_dynamic_join(my_df, r)
            x          y  z
1   15.930520 39.2834357 20
2   22.327434 21.1918363 15
3   34.371202 16.2156088 10
4   54.492467 59.5610437 36
5   12.100916 38.0095959 20
6   53.903381 12.7924881 12
7   56.680516  7.7623409  6
8   39.647868 28.6870821 16
9   37.746843 55.4444682 34
10   3.707176 35.9256580 19
11  12.358474 58.5702417 32
12  10.593405 43.9075507 26
13  41.221371 21.4036147 17
14  23.046223 25.8884214 15
15  46.190485  8.8926936  5
16  29.861955  0.7846545  3
17  43.057110 42.9339640 29
18  59.514366  6.1910541  6
19  22.802111 26.7770609 15
20  46.646713 38.4060627 23
21  56.082314 59.5103172 36
22  12.728551 29.7356147 14
23  39.100426 29.0609715 16
24   7.533306 10.4065401  7
25  16.033240 45.2892567 26
26  23.166846 27.2337294 15
27   0.803420 30.6701870 19
28  22.943277 12.4527068  9
29  52.181451 13.7194886 12
30  20.420940 35.7427198 21
31  28.924807 34.4923319 21
32  35.973950  4.6238628  4
33  29.612478  2.1324348  3
34  11.173056 38.5677295 20
35  49.642399 55.7169120 35
36  40.108004 35.8855453 23
37  47.654392 33.6540449 23
38   6.476618 31.5616634 19
39  43.422657 59.1057134 35
40  24.676466 30.4585093 21
41  49.256778 40.9672847 29
42  38.823612 36.0924731 22
43  46.975966 14.3321207 11
44  33.182179 15.4899556 10
45  31.783175 43.7585774 28
46  47.361374 27.1542499 17
47   1.399872 10.5076061  7
48  28.633804 44.8018962 27
49  43.938824  6.2992584  5
50  41.563893 51.8726969 35
51  28.657177 36.8786983 21
52  51.672569 33.4295723 24
53  26.285826 19.7266391  9
54  14.687837 27.1878867 14
55   4.240743 30.0264584 19
56   5.967970 10.8519817  7
57  18.976302 31.7778362 20
58  31.118056  4.5165447  4
59  39.720305 16.6653560 10
60  24.409811 12.7619712  9
61  54.772555 17.0874289 12
62  17.616202 53.7056462 32
63  27.543944 26.7741194 15
64  19.943680 46.7990934 26
65  39.052228 52.8371421 34
66  15.481007 24.7874526 14
67  28.712715  3.8285088  3
68  45.978640 20.1292495 17
69   5.054815 43.4235568 25
70  52.519280 20.2569200 18
71  20.344376 37.8248473 21
72  50.366421 50.4368732 36
73  20.801009 51.3678999 33
74  20.026496 23.4815569 15
75  28.581075 22.8296331 15
76  53.531900 53.7267256 36
77  51.860368 38.6589458 24
78  23.399373 44.4647189 27
79  46.639242 36.3182068 23
80  57.637080 54.1848967 36
81  26.079569 17.6238093  9
82  42.750881 11.4756066 11
83  23.999662 53.1870566 33
84  19.521129 30.2003691 20
85  45.425229 52.6234526 35
86  12.161535 11.3516173  8
87  42.667273 45.4861831 29
88   7.301515 43.4699336 25
89  14.729311 56.6234891 32
90   8.598263 32.8587952 19
91  14.377765 42.7046321 26
92   3.536063 23.3343060 13
93  38.537296  6.0523876  4
94  52.576153 55.6381253 36
95  46.734881 16.9939500 11
96  47.838530 35.4343895 23
97  27.316467  6.6216363  3
98  24.605045 50.4304219 33
99  48.652215 19.0778211 11
100 36.295997 46.9710802 28