如何从数据表中的列子集中提取唯一行?(How do I extract the unique rows from a subset of columns in a data table?)
我想从data.table中获取唯一的行,给出列的子集和
i
的条件。 最好的方法是什么? (在计算速度和短或可读语法方面“最佳”)set.seed(1) jk <- data.table(c1 = sample(letters,60,replace = TRUE), c2 = sample(c(TRUE,FALSE),60, replace = TRUE), c3 = sample(letters,60, replace = TRUE), c4 = sample.int(10,60, replace = TRUE) )
说我想找到
c1
和c2
的独特组合,其中c4
是10.我可以想到几种方法,但不确定什么是最佳的。 要提取的列是否有键可能也很重要。## works but gives an extra column jk[c4 >= 10, TRUE, keyby = list(c1,c2)] ## this removes extra column jk[c4 >= 10, TRUE, keyby = list(c1,c2)][,V1 := NULL] ## this seems like it could work ## but no j-expression with a keyby throws an error jk[c4 >= 10, , keyby = list(c1,c2)] ## using unique with .SD jk[c4 >= 10, unique(.SD), .SDcols = c("c1","c2")]
I would like to take the unique rows from a data.table, given a subset of columns and a condition in
i
. What is the best way of going about it? ("Best" in terms of computing speed and short or readable syntax)set.seed(1) jk <- data.table(c1 = sample(letters,60,replace = TRUE), c2 = sample(c(TRUE,FALSE),60, replace = TRUE), c3 = sample(letters,60, replace = TRUE), c4 = sample.int(10,60, replace = TRUE) )
Say I'd like to find the unique combinations of
c1
andc2
wherec4
is 10. I can think of a couple of ways to do it but am not sure what is optimal. Whether the columns to extract are keyed or not may also be important.## works but gives an extra column jk[c4 >= 10, TRUE, keyby = list(c1,c2)] ## this removes extra column jk[c4 >= 10, TRUE, keyby = list(c1,c2)][,V1 := NULL] ## this seems like it could work ## but no j-expression with a keyby throws an error jk[c4 >= 10, , keyby = list(c1,c2)] ## using unique with .SD jk[c4 >= 10, unique(.SD), .SDcols = c("c1","c2")]
原文:https://stackoverflow.com/questions/19574121
最满意答案
看起来你有一个JSON字符串。 请记住,JSON是无序的 ,因此如果下一次以不同的顺序出现字符串,则大多数sed,awk,cut解决方案将失败。
使用JSON解析器是最健壮的。
您可以将ruby与其JSON解析器库一起使用:
$ echo "$fullToken" | ruby -r json -e 'p JSON.parse($<.read)["token"];' "l0ng_Str1ng.of.d1fF3erent_charAct3rs"
或者,如果您不想要引用的字符串(这对Bash很有用):
$ echo "$fullToken" | ruby -r json -e 'puts JSON.parse($<.read)["token"];' l0ng_Str1ng.of.d1fF3erent_charAct3rs
或者用jq :
$ echo "$fullToken" | jq '.token' "l0ng_Str1ng.of.d1fF3erent_charAct3rs"
即使JSON字符串的顺序不同,所有这些解决方案都将起作用:
$ echo '{"type":"APP","token":"l0ng_Str1ng.of.d1fF3erent_charAct3rs"}' | jq '.token' "l0ng_Str1ng.of.d1fF3erent_charAct3rs" $ echo '{"token":"l0ng_Str1ng.of.d1fF3erent_charAct3rs", "type":"APP"}' | jq '.token' "l0ng_Str1ng.of.d1fF3erent_charAct3rs"
但是知道你应该使用JSON解析器,你也可以在Gnu Grep中使用一个看起来很好的PCRE:
$ echo "$fullToken" | grep -oP '(?<="token":)"([^"]*)'
或者在Perl中:
$ echo "$fullToken" | perl -lane 'print $1 if /(?<="token":)"([^"]*)/'
如果字符串的顺序不同,这两个也可以工作。
或者,使用POSIX awk:
$ echo "$fullToken" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/"token"/){print $(i+1)}}}'
或者,使用POSIX sed,您可以:
$ echo "$fullToken" | sed -E 's/.*"token":"([^"]*).*/\1/'
这些解决方案最强(使用JSON解析器)更脆弱(sed)。 但是我在那里的sed解决方案比其他解决方案更好,因为它将支持JSON字符串中的键,值的顺序不同。
Ps:如果你想从一行中删除引号,这对
sed
来说是一个很好的工作:$ echo '"quoted string"' "quoted string" $ echo '"quoted string"' | sed -E 's/^"(.*)"$/UN\1/' UNquoted string
It looks like you have a JSON string there. Keep in mind that JSON is unordered, so most sed, awk, cut solutions will fail if you string comes next time in a different order.
It is most robust to use a JSON parser.
You could use ruby with its JSON parser library:
$ echo "$fullToken" | ruby -r json -e 'p JSON.parse($<.read)["token"];' "l0ng_Str1ng.of.d1fF3erent_charAct3rs"
Or, if you don't want the quoted string (which is useful for Bash):
$ echo "$fullToken" | ruby -r json -e 'puts JSON.parse($<.read)["token"];' l0ng_Str1ng.of.d1fF3erent_charAct3rs
Or with jq:
$ echo "$fullToken" | jq '.token' "l0ng_Str1ng.of.d1fF3erent_charAct3rs"
All these solutions will work even if the JSON string is in a different order:
$ echo '{"type":"APP","token":"l0ng_Str1ng.of.d1fF3erent_charAct3rs"}' | jq '.token' "l0ng_Str1ng.of.d1fF3erent_charAct3rs" $ echo '{"token":"l0ng_Str1ng.of.d1fF3erent_charAct3rs", "type":"APP"}' | jq '.token' "l0ng_Str1ng.of.d1fF3erent_charAct3rs"
But KNOWING that you SHOULD use a JSON parser, you can also use a PCRE with a look behind in Gnu Grep:
$ echo "$fullToken" | grep -oP '(?<="token":)"([^"]*)'
Or in Perl:
$ echo "$fullToken" | perl -lane 'print $1 if /(?<="token":)"([^"]*)/'
Both of those also work if the string is in a different order.
Or, with POSIX awk:
$ echo "$fullToken" | awk -F"[,:}]" '{for(i=1;i<=NF;i++){if($i~/"token"/){print $(i+1)}}}'
Or, with POSIX sed, you can do:
$ echo "$fullToken" | sed -E 's/.*"token":"([^"]*).*/\1/'
Those solutions are presented strongest (use a JSON parser) to more fragile (sed). But the sed solution I have there is better than the other because it will support the key, values in the JSON string being in different order.
Ps: If you want to remove the quotes from a line, that is a great job for
sed
:$ echo '"quoted string"' "quoted string" $ echo '"quoted string"' | sed -E 's/^"(.*)"$/UN\1/' UNquoted string
相关问答
更多-
TCP/IP模型是一个________。[2023-10-02]
a -
下列中不属于面向对象的编程语言的是?[2022-05-30]
a -
使用sed,awk或perl从一行中提取11个字符的子字符串(extract a substring of 11 characters from a line using sed,awk or perl)[2022-08-05]
你可以做 grep -oP '(?<=/watch\?v=).{11}' 如果你的grep知道Perl正则表达式,或者 sed 's/.*\/watch?v=\(.\{11\}\).*/\1/g' You can do grep -oP '(?<=/watch\?v=).{11}' if your grep knows Perl regex, or sed 's/.*\/watch?v=\(.\{11\}\).*/\1/g' -
看起来你有一个JSON字符串。 请记住,JSON是无序的 ,因此如果下一次以不同的顺序出现字符串,则大多数sed,awk,cut解决方案将失败。 使用JSON解析器是最健壮的。 您可以将ruby与其JSON解析器库一起使用: $ echo "$fullToken" | ruby -r json -e 'p JSON.parse($<.read)["token"];' "l0ng_Str1ng.of.d1fF3erent_charAct3rs" 或者,如果您不想要引用的字符串(这对Bash很有用): $ e ...
-
MySQL在5.7.7版本中支持JSON http://mysqlserverteam.com/json-labs-release-native-json-data-type-and-binary-format/ 你必须纯粹在mysql中解析它然后我害怕你必须把它当作一个字符串并从中削减它(只是正常的字符串函数或使用正则表达式)这不是优雅但它会工作 CREATE TABLE testjson (`jsonfield` varchar(2000)) ; INSERT INTO testjson (`json ...
-
正则表达式 。 或者以更繁琐的方式拆分字符串 。 由于我不是一个大的正则表达式,我可能会使用.text()获得文本等效,然后将结果拆分为“:”,并获取第二个索引(这将是'Spartan'文本)。 Regular Expressions. Or by splitting the string in a more tedious fashion. Since I'm not a big regex-junkie, I would likely get the text-equivalent using .tex ...
-
要提取AWk中的最后一个字符,您可以使用: substr(var,length(var),1) 该脚本将是: awk -vFS=, -vOFS=, \ '{gsub("\"","")} FNR==4{ser=$2} FNR==5{loc=$2} FNR>8{gsub(" ",OFS);print loc,ser,FILENAME,substr(loc,length(loc),1),$0}' \ *.csv > formatted_log.csv 来自man awk: sub ...
-
用awk提取和分割(using awk to extract and split)[2023-10-20]
这应该工作: $ echo abc_def_ghi jkl_lmn_opq | awk -F_ '{ print $NF}' opq NF是一个内置变量,可存储多个字段。 当您用_分割行并告诉awk打印$NF您将打印最后一个字段。 但是,您可能并不总是需要字符串的最后部分。 在这种情况下,您可以在awk使用substr函数。 使用相同的示例,您可以: $ echo abc_def_ghi jkl_lmn_opq | awk ' { print substr($2,9) }' opq substr函数有3 ... -
好吧,你只需要一个awk命令。 不需要其他工具 $ str="Cpu(s): 1.9%us, 2.1%sy, 1.5%ni, 94.5%id, 0.8%wa, 0.0%hi, 0.1%si, 0.0%st" $ echo $str | awk '{print $2+$3+$4+0}' 5.5 well, you just need one awk command. No need for other tools $ str="Cpu(s): 1.9%us, 2.1%sy, 1.5%n ...
-
这可以使用正则表达式来实现 不合理,不,因为正则表达式不适合自己解释像JSON这样的结构; 与HTML一样,您需要一个合适的解析器。 相反,使用几个Java库中的任何一个来解析JSON,然后遍历其内容; 在JSON网站的底部有一个列表(我看到Gson使用了很多,但有很多选项)。 This can be achieved using Regex or not Not reasonably, no, because regular expressions are not well-suited to inter ...