多索引的For循环

多索引的For循环,r,for-loop,apply,R,For Loop,Apply,我知道在R中应该避免for循环,而应该使用向量化操作 我想用for循环来解决这个问题,然后尝试使用apply系列,然后也在Rcpp中使用 我加载一个包含一列密码(字母数字)的数据集 加载后(对于速度,是一个示例),我希望根据一些条件“包含较低字符”、“包含数字”等,创建值为(0,1)的新列 这里是我试图做的,但它不起作用——这意味着我创建的每个列都有相同的值 library(tidyverse) set.seed(123) # load dataset from url, skip the fi

我知道在R中应该避免for循环,而应该使用向量化操作

我想用
for
循环来解决这个问题,然后尝试使用
apply
系列,然后也在Rcpp中使用

我加载一个包含一列密码(字母数字)的数据集

加载后(对于速度,是一个示例),我希望根据一些条件“包含较低字符”、“包含数字”等,创建值为(0,1)的新列

这里是我试图做的,但它不起作用——这意味着我创建的每个列都有相同的值

library(tidyverse)
set.seed(123)
# load dataset from url, skip the first 16 rows
df <- read.csv('http://datashaping.com/passwords.txt', header = F, skip = 16) %>%
  sample_frac(.001) %>% 
  rename(password = V1)

patterns = c("[a-z]","[A-Z]","[0-9]+")

df$has_lower <- 0 
df$has_upper <- 0
df$has_numeric <- 0

for(i in 1:nrow(df)){
    for(j in patterns){
        n <- ifelse(grepl(j, df$password[i]),1,0)
        }
    df$has_lower[i] <- n
    df$has_upper[i] <- n 
    df$has_numeric[i] <- n
}

首先,您需要在j循环中更新has.lower has.upper和has.numeric,否则您的
n
在这3种情况下保持不变。为此,您需要能够循环访问has.lower has.upper和has.numeric列的名称:

names <- c("has_lower","has_upper","has_numeric")

for(i in 1:nrow(df)){
  for(j in 1:length(patterns)){
    df[i,(names[j])] <- as.numeric(grepl(j, df$password[i]))
  }
}
注意(与您的问题无关):

我建议您使用
fread
函数读取数据集,因为它相当大

df = fread('http://datashaping.com/passwords.txt', header = F, skip = 16)%>%
  sample_frac(.001) %>% 
  rename(password = V1)

如果我们只命名你的模式向量,我们可以简化事情。比如说

patterns = c(has_lower="[a-z]",
             has_upper="[A-Z]",
             has_numeric="[0-9]+")

for(pattern in names(patterns)) {
  df[, pattern] = as.numeric(grepl(patterns[pattern], df$password))
}

基本上,我们只是循环遍历每个名称,获取与该名称对应的正则表达式,然后进行匹配并添加列。

数据帧首先是一个列表

因此,您可以简单地执行以下操作:

df[c("has_lower", "has_upper", "has_numeric")] <- 
  lapply(patterns, function(pattern) grepl(pattern, df$password) + 0)

df[c(“has_lower”、“has_upper”、“has_numeric”)]什么是“不起作用”呢?你有错误吗?一些意外的输出?在寻求帮助时,您应该包括一个简单的示例输入和所需的输出,用于测试和验证可能的解决方案。@MrFlick您可以复制运行上述代码的整个示例。它包含指向URL文件的链接以填充df。我将添加输出错误(我创建的每个列都有相同的值),但您没有给出所需的结果。使用
sample\u frac()
这样的东西,如果不设定种子,是不可复制的(另外,这确实依赖于
dplyr
,这在代码中没有明确提到)。我不知道为什么您会认为当您为每个列分配相同的
n
值时,列会不同。@MrFlick editedI将删除
[rcpp]
标记,因为这与rcpp无关。您能解释一下
df[I,(name[j])]
的含义吗?我很难理解这个。。。关于
fread
,如果您想了解它,我会发布一个问题。
df[I,(names[j])
为以
names[j]
命名的列选择行
I
names[j]
周围的括号告诉R必须使用变量
names[j]
的值来查找
df
中的相应列。在
df
中没有名为
names[j]
的列,但是有名为
的列具有较低的
具有较高的
等…谢谢!非常清楚。在第二种方法中,我得到错误
检查,即.data.table(DT)=TRUE。否则,:=和
:=
(…)被定义为仅以特定方式在j中使用一次。请参阅帮助(“:=”。
这是我的错,我假设'df'是一个data.table,因为我使用'fread'读取您的数据。我将更新它。我添加了
setDT
,它可以工作,即使它返回“TRUE/FALSE”而不是0/1I,我在
中得到错误
错误:=
(c(“has_lower”,“has_upper”,“has_numeric”),lappy(patterns,:找不到函数):“
。我做错了什么?我已经加载了
数据。表
它就像一个符咒。我唯一的问题是:
df[,I]是什么
mean:添加第i列?它可以提取或添加一列。
i
可以是返回第i列的数字,也可以是返回该列名称的字符/字符串。
patterns = c(has_lower="[a-z]",
             has_upper="[A-Z]",
             has_numeric="[0-9]+")

for(pattern in names(patterns)) {
  df[, pattern] = as.numeric(grepl(patterns[pattern], df$password))
}
df[c("has_lower", "has_upper", "has_numeric")] <- 
  lapply(patterns, function(pattern) grepl(pattern, df$password) + 0)